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/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",
|
|
@@ -1959,6 +2279,19 @@ function workflowOrgSlotKey(orgId, kind) {
|
|
|
1959
2279
|
__name(workflowOrgSlotKey, "workflowOrgSlotKey");
|
|
1960
2280
|
__name2(workflowOrgSlotKey, "workflowOrgSlotKey");
|
|
1961
2281
|
var WORKFLOW_CONNECTION_KEY_RE = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
2282
|
+
var WORKFLOW_JOB_MODEL_SOURCE_LABELS = {
|
|
2283
|
+
stamp: "lease stamp",
|
|
2284
|
+
initData: "run input",
|
|
2285
|
+
default: "placeholder default",
|
|
2286
|
+
node: "node.model",
|
|
2287
|
+
env: "platform default",
|
|
2288
|
+
org: "org default"
|
|
2289
|
+
};
|
|
2290
|
+
function workflowJobModelSourceLabel(source) {
|
|
2291
|
+
return WORKFLOW_JOB_MODEL_SOURCE_LABELS[source];
|
|
2292
|
+
}
|
|
2293
|
+
__name(workflowJobModelSourceLabel, "workflowJobModelSourceLabel");
|
|
2294
|
+
__name2(workflowJobModelSourceLabel, "workflowJobModelSourceLabel");
|
|
1962
2295
|
function scheduledTimeKey(scheduledTime) {
|
|
1963
2296
|
return scheduledTime.replace(/[^0-9TZ]/g, "");
|
|
1964
2297
|
}
|
|
@@ -1981,195 +2314,6 @@ var WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS = [
|
|
|
1981
2314
|
];
|
|
1982
2315
|
var WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
1983
2316
|
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
2317
|
var WORKFLOW_GOAL_JUDGE_SELF = "$self";
|
|
2174
2318
|
function workflowGoalJudgeKind(judge) {
|
|
2175
2319
|
return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
|
|
@@ -2457,7 +2601,36 @@ var WORKFLOW_AUDIT_EVENTS = [
|
|
|
2457
2601
|
"workflow.export.auto_pushed",
|
|
2458
2602
|
"workflow.retention.restamped",
|
|
2459
2603
|
"workflow.retention.reaped",
|
|
2460
|
-
"workflow.run.schema_migrated"
|
|
2604
|
+
"workflow.run.schema_migrated",
|
|
2605
|
+
// --- per-step model selection (Workflow Model Selection plan 6.5 / Appendix C.4) ---
|
|
2606
|
+
/** A `PATCH /admin/orgs/:orgId/workflow-policy` that changed the `models` block (who, what moved). */
|
|
2607
|
+
"workflow.policy.models_changed",
|
|
2608
|
+
/** A step's invocation hopped to another leg of its class — `{from, to, reason}`, priced at the served model. */
|
|
2609
|
+
"workflow.step.model_fallback",
|
|
2610
|
+
// --- autonomy envelope (Workflow autonomy plan A1; research/consent-gates.md §H2) ---
|
|
2611
|
+
/**
|
|
2612
|
+
* A start the consent ladder would have PARKED was admitted by `workflowPolicy.autonomy` instead —
|
|
2613
|
+
* `WorkflowRunAutonomyAppliedPayload`. Deliberately NOT `workflow.run.gate_cleared`: nothing was
|
|
2614
|
+
* gated and nobody approved it, and conflating the two would make "who approved this run"
|
|
2615
|
+
* unanswerable for every run of either kind (§H2 "Audit").
|
|
2616
|
+
*/
|
|
2617
|
+
"workflow.run.autonomy_applied",
|
|
2618
|
+
// --- run budget cap enforcement (Job-tier billing plan D4; BAC-677) ---
|
|
2619
|
+
/**
|
|
2620
|
+
* The audit twin of the `run.budget_exceeded` run event (WJB-B2a): the run overshot its
|
|
2621
|
+
* `budget.maxCredits` on its LAST step and completed anyway, `budget.exceeded: true`. The budget family
|
|
2622
|
+
* already mirrors run events here — `workflow.run.budget_parked` / `workflow.run.budget_raised` are the
|
|
2623
|
+
* twins of `run.budget_parked` / `run.budget_raised` — and an organisation reviewing what it was charged
|
|
2624
|
+
* needs the overshoot in the audit store beside the raise that preceded it, not only in the run's own
|
|
2625
|
+
* event stream.
|
|
2626
|
+
*
|
|
2627
|
+
* Declared with the run event rather than after it because the emitter port
|
|
2628
|
+
* (`WorkflowAuditPort.action`, typed `workflow.run.${string}`) does not check against this tuple: a name
|
|
2629
|
+
* that is NOT declared here is written to the audit store all the same and no compiler says so.
|
|
2630
|
+
* Declaring it is what makes the later emitter checkable. `workflow.run.budget_parked` is likewise
|
|
2631
|
+
* declared and not yet emitted.
|
|
2632
|
+
*/
|
|
2633
|
+
"workflow.run.budget_exceeded"
|
|
2461
2634
|
];
|
|
2462
2635
|
var WORKFLOW_AUDIT_METADATA_MAX_BYTES = 4 * 1024;
|
|
2463
2636
|
function isWorkflowAuditEvent(action) {
|
|
@@ -3233,7 +3406,7 @@ function modelTemplateInvalidMessage(model, why) {
|
|
|
3233
3406
|
__name(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
|
|
3234
3407
|
__name4(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
|
|
3235
3408
|
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>}")}`;
|
|
3409
|
+
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
3410
|
}
|
|
3238
3411
|
__name(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
|
|
3239
3412
|
__name4(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
|
|
@@ -4008,6 +4181,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4008
4181
|
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
4182
|
}
|
|
4010
4183
|
}, "checkRequiredConnections");
|
|
4184
|
+
const jobClassifiablePin = /* @__PURE__ */ __name4((model) => {
|
|
4185
|
+
const pin = staticModelPin(model);
|
|
4186
|
+
const modelClass = modelClassOf(pin);
|
|
4187
|
+
if (modelClass === void 0) return pin;
|
|
4188
|
+
const codes = opts.classMap?.[modelClass];
|
|
4189
|
+
if (!codes) return void 0;
|
|
4190
|
+
const jobProviders = opts.policy?.jobProviders;
|
|
4191
|
+
for (const code of codes) {
|
|
4192
|
+
const p = classifyModelProvider(code);
|
|
4193
|
+
if (p === null) continue;
|
|
4194
|
+
if (jobProviders && !jobProviders.includes(p)) continue;
|
|
4195
|
+
return code;
|
|
4196
|
+
}
|
|
4197
|
+
return void 0;
|
|
4198
|
+
}, "jobClassifiablePin");
|
|
4011
4199
|
const checkTier = /* @__PURE__ */ __name4((node, path) => {
|
|
4012
4200
|
const id = singleId(node);
|
|
4013
4201
|
if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
|
|
@@ -4016,7 +4204,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4016
4204
|
if (node.harness !== void 0 && node.tier !== "job") {
|
|
4017
4205
|
err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path}.harness`, id);
|
|
4018
4206
|
}
|
|
4019
|
-
const provider = node.type === "agent" ? classifyModelProvider(
|
|
4207
|
+
const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
|
|
4020
4208
|
if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
|
|
4021
4209
|
err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path}.harness`, id);
|
|
4022
4210
|
}
|
|
@@ -4040,6 +4228,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4040
4228
|
}
|
|
4041
4229
|
const pin = parsed.kind === "template" ? parsed.template.default : node.model;
|
|
4042
4230
|
if (pin === void 0) return;
|
|
4231
|
+
if (isModelClassRef(pin)) return;
|
|
4043
4232
|
const inContext = /* @__PURE__ */ __name4((message) => parsed.kind === "template" ? `${message} (the default of ${parsed.template.placeholder})` : message, "inContext");
|
|
4044
4233
|
const registry = opts.approvedModels;
|
|
4045
4234
|
if (registry === void 0) return;
|
|
@@ -4053,6 +4242,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4053
4242
|
const resolved = normalizeModelId(pin, registry);
|
|
4054
4243
|
if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path}.model`, id);
|
|
4055
4244
|
}, "checkModel");
|
|
4245
|
+
const checkTaskClass = /* @__PURE__ */ __name4((node, path) => {
|
|
4246
|
+
if (node.type !== "agent" || node.taskClass === void 0) return;
|
|
4247
|
+
if (!opts.static) return;
|
|
4248
|
+
if (typeof node.model === "string" && node.model.trim()) return;
|
|
4249
|
+
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));
|
|
4250
|
+
}, "checkTaskClass");
|
|
4056
4251
|
const checkWorkspace = /* @__PURE__ */ __name4((node, path) => {
|
|
4057
4252
|
const id = singleId(node);
|
|
4058
4253
|
const ws = workspaceOf(node);
|
|
@@ -4139,6 +4334,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4139
4334
|
checkTimeout(node, path);
|
|
4140
4335
|
checkTier(node, path);
|
|
4141
4336
|
checkModel(node, path);
|
|
4337
|
+
checkTaskClass(node, path);
|
|
4142
4338
|
checkRetry(node, path);
|
|
4143
4339
|
checkWorkspace(node, path);
|
|
4144
4340
|
if (!opts.static) {
|
|
@@ -7078,6 +7274,55 @@ function graphHasJobTierStep(envelopeOrGraph) {
|
|
|
7078
7274
|
}
|
|
7079
7275
|
__name(graphHasJobTierStep, "graphHasJobTierStep");
|
|
7080
7276
|
__name4(graphHasJobTierStep, "graphHasJobTierStep");
|
|
7277
|
+
function jobTierSteps(envelopeOrGraph) {
|
|
7278
|
+
const out = [];
|
|
7279
|
+
if (!envelopeOrGraph || typeof envelopeOrGraph !== "object") return out;
|
|
7280
|
+
const env = envelopeOrGraph;
|
|
7281
|
+
const graph = Array.isArray(envelopeOrGraph) ? envelopeOrGraph : env.definition?.graph ?? [];
|
|
7282
|
+
if (!Array.isArray(graph)) return out;
|
|
7283
|
+
for (const entry of graph) collectJobTierSteps(entry, out);
|
|
7284
|
+
return out;
|
|
7285
|
+
}
|
|
7286
|
+
__name(jobTierSteps, "jobTierSteps");
|
|
7287
|
+
__name4(jobTierSteps, "jobTierSteps");
|
|
7288
|
+
function jobTierStepIds(envelopeOrGraph) {
|
|
7289
|
+
return jobTierSteps(envelopeOrGraph).map((s) => s.stepId);
|
|
7290
|
+
}
|
|
7291
|
+
__name(jobTierStepIds, "jobTierStepIds");
|
|
7292
|
+
__name4(jobTierStepIds, "jobTierStepIds");
|
|
7293
|
+
function collectJobTierSteps(entry, out) {
|
|
7294
|
+
const n2 = armEntry2(entry);
|
|
7295
|
+
if (!n2 || typeof n2 !== "object") return;
|
|
7296
|
+
const node = n2;
|
|
7297
|
+
const ws = node.workspace;
|
|
7298
|
+
if (node.tier === "job" || ws !== void 0 && ws !== "inherit") {
|
|
7299
|
+
const stepId = typeof node.id === "string" && node.id ? node.id : "(unnamed)";
|
|
7300
|
+
const model = typeof node.model === "string" && node.model.trim() ? node.model.trim() : void 0;
|
|
7301
|
+
out.push(model === void 0 ? {
|
|
7302
|
+
stepId
|
|
7303
|
+
} : {
|
|
7304
|
+
stepId,
|
|
7305
|
+
model
|
|
7306
|
+
});
|
|
7307
|
+
}
|
|
7308
|
+
switch (node.type) {
|
|
7309
|
+
case "parallel":
|
|
7310
|
+
if (Array.isArray(node.steps)) for (const s of node.steps) collectJobTierSteps(s, out);
|
|
7311
|
+
return;
|
|
7312
|
+
case "conditional":
|
|
7313
|
+
if (Array.isArray(node.steps)) for (const s of node.steps) collectJobTierSteps(s, out);
|
|
7314
|
+
if (node.otherwise !== void 0) collectJobTierSteps(node.otherwise, out);
|
|
7315
|
+
return;
|
|
7316
|
+
case "foreach":
|
|
7317
|
+
case "loop":
|
|
7318
|
+
collectJobTierSteps(node.step, out);
|
|
7319
|
+
return;
|
|
7320
|
+
default:
|
|
7321
|
+
return;
|
|
7322
|
+
}
|
|
7323
|
+
}
|
|
7324
|
+
__name(collectJobTierSteps, "collectJobTierSteps");
|
|
7325
|
+
__name4(collectJobTierSteps, "collectJobTierSteps");
|
|
7081
7326
|
|
|
7082
7327
|
// src/types/workflow.ts
|
|
7083
7328
|
function createStep(s) {
|
|
@@ -7294,6 +7539,10 @@ var LuaWorkflow = class {
|
|
|
7294
7539
|
maxDurationSeconds: cfg.budget?.maxDurationSeconds ?? (hitl ? WORKFLOW_HITL_MAX_DURATION_SECONDS : WORKFLOW_DEFAULT_MAX_DURATION_SECONDS)
|
|
7295
7540
|
});
|
|
7296
7541
|
const envelope = {
|
|
7542
|
+
// A plain build/push is ALWAYS marker 1 (plan 6.4's compatibility row: "a CLI test that a plain push of
|
|
7543
|
+
// such a definition stays at 1"). Moving a definition to 2 — the effort marker — is an explicit act
|
|
7544
|
+
// (`lua push --apply-effort`, or a new compose while assignment is on), never a side effect of the SDK
|
|
7545
|
+
// gaining an `effort` member.
|
|
7297
7546
|
luaWorkflow: 1,
|
|
7298
7547
|
budget,
|
|
7299
7548
|
definition: defined({
|
|
@@ -7688,6 +7937,10 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
|
|
|
7688
7937
|
promptTemplate: templateText(opts.prompt),
|
|
7689
7938
|
outputSchema: schemaToJson(opts.outputSchema),
|
|
7690
7939
|
model: opts.model,
|
|
7940
|
+
taskClass: opts.taskClass,
|
|
7941
|
+
requires: opts.requires,
|
|
7942
|
+
modelReason: opts.modelReason,
|
|
7943
|
+
effort: opts.effort,
|
|
7691
7944
|
toolScope: opts.toolScope,
|
|
7692
7945
|
systemPrompt: opts.systemPrompt,
|
|
7693
7946
|
timeoutSeconds: opts.timeoutSeconds,
|