lua-cli 3.31.0 → 3.32.1
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 +81 -5
- package/dist/api-exports.js +686 -126
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +2003 -308
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.d.ts +37 -3
- package/dist/workflow-builder.js +658 -117
- package/dist/workflow-builder.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/api/LuaWorkflow.md +44 -28
- package/docs/api/Workflows.md +2 -1
- package/docs/workflows/approvals.md +14 -1
- package/docs/workflows/connections-in-coding-turns.md +1 -0
- package/docs/workflows/git-credentials.md +22 -1
- package/docs/workflows/goals.md +46 -0
- package/docs/workflows/recovery.md +6 -2
- package/docs/workflows/replay-local.md +10 -10
- package/docs/workflows/schedules.md +15 -0
- package/docs/workflows/testing-offline.md +22 -19
- package/docs/workflows/workspaces-and-long-steps.md +2 -0
- package/package.json +3 -3
- package/template/examples/workflows/CLAUDE.md +16 -13
- package/template/examples/workflows/pr-review-round.ts +57 -20
- package/template/examples/workflows/provision-tenant.ts +25 -8
- package/template/examples/workflows/refund-approval.ts +30 -17
- package/template/examples/workflows/support-triage.ts +59 -22
- package/template/examples/workflows/ticket-to-pr.ts +103 -31
- package/template/examples/workflows/vendor-invoices.ts +69 -16
- package/template/package.json +1 -1
package/dist/api-exports.js
CHANGED
|
@@ -514,7 +514,6 @@ function luaClientMetricLabels(client) {
|
|
|
514
514
|
const canonical2 = parseLuaClientHeader(serializeLuaClientHeader(client));
|
|
515
515
|
return {
|
|
516
516
|
client_family: canonical2?.app ?? "unknown",
|
|
517
|
-
client_version: canonical2?.version ?? "unknown",
|
|
518
517
|
client_attribution: canonical2?.attribution ?? "unknown"
|
|
519
518
|
};
|
|
520
519
|
}
|
|
@@ -582,6 +581,59 @@ function scheduledTimeKey(scheduledTime) {
|
|
|
582
581
|
function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
|
|
583
582
|
return scheduledWorkflowRunId(jobId, scheduledTime);
|
|
584
583
|
}
|
|
584
|
+
function groupCount(re) {
|
|
585
|
+
let n2 = GROUP_COUNT.get(re);
|
|
586
|
+
if (n2 === void 0) {
|
|
587
|
+
n2 = new RegExp(`${re.source}|`, re.flags.replace("g", "")).exec("").length - 1;
|
|
588
|
+
GROUP_COUNT.set(re, n2);
|
|
589
|
+
}
|
|
590
|
+
return n2;
|
|
591
|
+
}
|
|
592
|
+
function applyPatterns(text, patterns) {
|
|
593
|
+
let out = text;
|
|
594
|
+
for (const { re, suffix } of patterns) {
|
|
595
|
+
re.lastIndex = 0;
|
|
596
|
+
if (!re.test(out)) continue;
|
|
597
|
+
re.lastIndex = 0;
|
|
598
|
+
const groups = groupCount(re);
|
|
599
|
+
out = out.replace(re, (...args) => {
|
|
600
|
+
const kept = args.slice(1, 1 + groups).map((g) => typeof g === "string" ? g : "");
|
|
601
|
+
if (suffix && kept.length > 0) {
|
|
602
|
+
const tail = kept[kept.length - 1];
|
|
603
|
+
return `${kept.slice(0, -1).join("")}${REDACTED_PLACEHOLDER}${tail}`;
|
|
604
|
+
}
|
|
605
|
+
return `${kept.join("")}${REDACTED_PLACEHOLDER}`;
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
return out;
|
|
609
|
+
}
|
|
610
|
+
function scrubSecretText(text) {
|
|
611
|
+
if (typeof text !== "string" || text.length < 4) return text;
|
|
612
|
+
return applyPatterns(applyPatterns(text, SECRET_LITERAL_PATTERNS), SECRET_PAIR_PATTERNS);
|
|
613
|
+
}
|
|
614
|
+
function scrubSecretLines(lines) {
|
|
615
|
+
return lines.map((l) => typeof l === "string" ? scrubSecretText(l) : l);
|
|
616
|
+
}
|
|
617
|
+
function messageText(value3) {
|
|
618
|
+
if (typeof value3 === "string") return value3;
|
|
619
|
+
if (value3 instanceof Error) return value3.message;
|
|
620
|
+
if (value3 && typeof value3 === "object") {
|
|
621
|
+
const m = value3.message;
|
|
622
|
+
if (typeof m === "string") return m;
|
|
623
|
+
try {
|
|
624
|
+
return JSON.stringify(value3);
|
|
625
|
+
} catch {
|
|
626
|
+
return "";
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return value3 === void 0 || value3 === null ? "" : String(value3);
|
|
630
|
+
}
|
|
631
|
+
function scrubProviderMessage(raw, max = PROVIDER_MESSAGE_MAX_CHARS) {
|
|
632
|
+
const text = messageText(raw).replace(/\s+/g, " ").trim();
|
|
633
|
+
if (!text) return void 0;
|
|
634
|
+
const out = scrubSecretText(text);
|
|
635
|
+
return out.length > max ? `${out.slice(0, max - 1)}\u2026` : out;
|
|
636
|
+
}
|
|
585
637
|
function isWorkflowAuditEvent(action) {
|
|
586
638
|
return typeof action === "string" && WORKFLOW_AUDIT_EVENTS.includes(action);
|
|
587
639
|
}
|
|
@@ -676,7 +728,7 @@ ${PREAMBLE}
|
|
|
676
728
|
|
|
677
729
|
${items.join("\n\n")}`;
|
|
678
730
|
}
|
|
679
|
-
var __defProp2, __name2, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE;
|
|
731
|
+
var __defProp2, __name2, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE;
|
|
680
732
|
var init_dist = __esm({
|
|
681
733
|
"../shared-types/dist/index.mjs"() {
|
|
682
734
|
"use strict";
|
|
@@ -1688,6 +1740,27 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
1688
1740
|
...WORKFLOW_RUN_IDLE,
|
|
1689
1741
|
...WORKFLOW_RUN_TERMINAL
|
|
1690
1742
|
];
|
|
1743
|
+
WORKFLOW_STEP_STATUSES = [
|
|
1744
|
+
"pending",
|
|
1745
|
+
"ready",
|
|
1746
|
+
"waiting",
|
|
1747
|
+
"dispatched",
|
|
1748
|
+
"claimed",
|
|
1749
|
+
"running",
|
|
1750
|
+
"suspended",
|
|
1751
|
+
"cancellation_requested",
|
|
1752
|
+
"completed",
|
|
1753
|
+
"failed",
|
|
1754
|
+
"skipped",
|
|
1755
|
+
"cancelled",
|
|
1756
|
+
"timeout",
|
|
1757
|
+
"reaped"
|
|
1758
|
+
];
|
|
1759
|
+
WORKFLOW_STEP_IN_FLIGHT = [
|
|
1760
|
+
"claimed",
|
|
1761
|
+
"running",
|
|
1762
|
+
"cancellation_requested"
|
|
1763
|
+
];
|
|
1691
1764
|
ARCHIVE_WINDOW_MARGIN_DAYS = 7;
|
|
1692
1765
|
__name(shouldSkipArchive, "shouldSkipArchive");
|
|
1693
1766
|
__name2(shouldSkipArchive, "shouldSkipArchive");
|
|
@@ -1717,11 +1790,90 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
1717
1790
|
__name2(workflowOccurrenceId, "workflowOccurrenceId");
|
|
1718
1791
|
__name(workflowOrgSlotKey, "workflowOrgSlotKey");
|
|
1719
1792
|
__name2(workflowOrgSlotKey, "workflowOrgSlotKey");
|
|
1793
|
+
WORKFLOW_CONNECTION_KEY_RE = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
1720
1794
|
__name(scheduledTimeKey, "scheduledTimeKey");
|
|
1721
1795
|
__name2(scheduledTimeKey, "scheduledTimeKey");
|
|
1722
1796
|
__name(scheduledWorkflowRunIdForTime, "scheduledWorkflowRunIdForTime");
|
|
1723
1797
|
__name2(scheduledWorkflowRunIdForTime, "scheduledWorkflowRunIdForTime");
|
|
1724
1798
|
WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
1799
|
+
REDACTED_PLACEHOLDER = "[REDACTED]";
|
|
1800
|
+
PROVIDER_MESSAGE_MAX_CHARS = 300;
|
|
1801
|
+
SECRET_LITERAL_PATTERNS = [
|
|
1802
|
+
{
|
|
1803
|
+
re: /\b(github_pat_)[A-Za-z0-9_]{16,}/g
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
re: /\b(gh[pousr]_)[A-Za-z0-9]{16,}/g
|
|
1807
|
+
},
|
|
1808
|
+
{
|
|
1809
|
+
re: /\b(glpat-)[A-Za-z0-9_-]{16,}/g
|
|
1810
|
+
},
|
|
1811
|
+
{
|
|
1812
|
+
re: /\b(sk-ant-)[A-Za-z0-9_-]{16,}/g
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
re: /\b(sk-)(?!ant-)[A-Za-z0-9_-]{20,}/g
|
|
1816
|
+
},
|
|
1817
|
+
{
|
|
1818
|
+
re: /\b(AKIA)[A-Z0-9]{16}\b/g
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
re: /\b(xox[abprs]-)[A-Za-z0-9-]{10,}/g
|
|
1822
|
+
},
|
|
1823
|
+
{
|
|
1824
|
+
re: /\b(AIza)[0-9A-Za-z_-]{35}/g
|
|
1825
|
+
},
|
|
1826
|
+
{
|
|
1827
|
+
re: /\b(ya29\.)[A-Za-z0-9_-]{20,}/g
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
re: /\b(eyJ)[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g
|
|
1831
|
+
},
|
|
1832
|
+
{
|
|
1833
|
+
re: /(-----BEGIN [A-Z ]*PRIVATE KEY-----)[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g
|
|
1834
|
+
},
|
|
1835
|
+
// `https://x-access-token:<token>@github.com/…` (the git credential shape the pod scrubbed already)
|
|
1836
|
+
{
|
|
1837
|
+
re: /\b(x-access-token:)[^@\s]+(@)/g,
|
|
1838
|
+
suffix: true
|
|
1839
|
+
}
|
|
1840
|
+
];
|
|
1841
|
+
SECRET_NAME = "(?:authorization|proxy-authorization|x-api-key|x-wf-[a-z-]*key|x-internal-auth|api[_-]?key|apikey|access[_-]?key|secret[_-]?key|private[_-]?key|client[_-]?secret|secret|password|passwd|pwd|passphrase|token|credentials?)";
|
|
1842
|
+
SECRET_PAIR_PATTERNS = [
|
|
1843
|
+
// `Authorization: Bearer x`, `x-api-key: x`, `AWS_SECRET_ACCESS_KEY=x`, `SVC_JOB_KEY=x`, `"apiKey": "x"`,
|
|
1844
|
+
// `FOO_TOKEN=x`, `secretKey=x`, `password=x`. Groups: the char before the name, the name, the separator
|
|
1845
|
+
// (with its quotes), the scheme word — all kept; the value goes. A value a literal rule already replaced
|
|
1846
|
+
// (`x-access-token:[REDACTED]@host`) is left alone so the host after it survives.
|
|
1847
|
+
{
|
|
1848
|
+
re: new RegExp(`(^|[^A-Za-z0-9])((?:[A-Za-z0-9-]+[_-])?${SECRET_NAME}|[A-Za-z0-9-]+_key)(["']?\\s*[:=]\\s*["']?)((?:basic\\s+|bearer\\s+|token\\s+)?)(?!\\[REDACTED\\])[^\\s"',;)}&]{4,}`, "gi")
|
|
1849
|
+
},
|
|
1850
|
+
// `?token=x`, `&key=x`, `&X-Amz-Signature=x`, `&sig=x`
|
|
1851
|
+
{
|
|
1852
|
+
re: /([?&](?:token|key|api[_-]?key|apikey|access[_-]?token|id[_-]?token|auth|sig|signature|secret|password|pwd|x-amz-signature|x-amz-credential|x-amz-security-token)=)[^&\s"'#]+/gi
|
|
1853
|
+
},
|
|
1854
|
+
// `mongodb+srv://user:pass@host`, `postgres://user:pass@host`, `https://user:pass@host`
|
|
1855
|
+
{
|
|
1856
|
+
re: /(\/\/[^\s/:@]+:)[^\s/@]+(@)/g,
|
|
1857
|
+
suffix: true
|
|
1858
|
+
},
|
|
1859
|
+
// `Basic <base64>` / `bearer <short token>` (the literal list needs ≥ 16 chars; any case)
|
|
1860
|
+
{
|
|
1861
|
+
re: /\b((?:Basic|Bearer)\s+)(?!\[REDACTED\])[A-Za-z0-9+/=_.-]{8,}/gi
|
|
1862
|
+
}
|
|
1863
|
+
];
|
|
1864
|
+
GROUP_COUNT = /* @__PURE__ */ new WeakMap();
|
|
1865
|
+
__name(groupCount, "groupCount");
|
|
1866
|
+
__name2(groupCount, "groupCount");
|
|
1867
|
+
__name(applyPatterns, "applyPatterns");
|
|
1868
|
+
__name2(applyPatterns, "applyPatterns");
|
|
1869
|
+
__name(scrubSecretText, "scrubSecretText");
|
|
1870
|
+
__name2(scrubSecretText, "scrubSecretText");
|
|
1871
|
+
__name(scrubSecretLines, "scrubSecretLines");
|
|
1872
|
+
__name2(scrubSecretLines, "scrubSecretLines");
|
|
1873
|
+
__name(messageText, "messageText");
|
|
1874
|
+
__name2(messageText, "messageText");
|
|
1875
|
+
__name(scrubProviderMessage, "scrubProviderMessage");
|
|
1876
|
+
__name2(scrubProviderMessage, "scrubProviderMessage");
|
|
1725
1877
|
WORKFLOW_AUDIT_EVENTS = [
|
|
1726
1878
|
// --- definitions / versions / templates (13, 11 §11.11.5) ---
|
|
1727
1879
|
"workflow.published",
|
|
@@ -1843,7 +1995,11 @@ listed here; never invent a target.`;
|
|
|
1843
1995
|
// ../workflow-graph/dist/index.mjs
|
|
1844
1996
|
import { createHash } from "crypto";
|
|
1845
1997
|
import { z as z4 } from "zod";
|
|
1998
|
+
import { z as z22 } from "zod";
|
|
1846
1999
|
import { createHash as createHash2 } from "crypto";
|
|
2000
|
+
function sleepUntilUnsupportedMessage(id) {
|
|
2001
|
+
return `the engine does not execute \`sleepUntil\` yet (node "${id}") \u2014 replace it with a \`sleep\` node with a \`duration\` in ms, e.g. { type: 'sleep', id: '${id}', duration: ${SLEEP_UNTIL_REPLACEMENT.duration} }`;
|
|
2002
|
+
}
|
|
1847
2003
|
function fillPolicy(node, defaultTimeout) {
|
|
1848
2004
|
if (node.tier === void 0 && node.workspace !== void 0 && node.workspace !== "inherit") node.tier = "job";
|
|
1849
2005
|
if (node.timeoutSeconds === void 0) node.timeoutSeconds = node.tier === "job" ? WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS : defaultTimeout;
|
|
@@ -1938,6 +2094,12 @@ function withDefaultsFilled(g) {
|
|
|
1938
2094
|
out.definition.graph.forEach(fillEntry);
|
|
1939
2095
|
return out;
|
|
1940
2096
|
}
|
|
2097
|
+
function isConnectionKeyShaped(value22) {
|
|
2098
|
+
return WORKFLOW_CONNECTION_KEY_RE.test(value22) && !CONNECTION_ID_HEX_RE.test(value22);
|
|
2099
|
+
}
|
|
2100
|
+
function connectionKeyUndeclaredMessage(path3, key) {
|
|
2101
|
+
return `${path3} '${key}' is neither a connection id nor a declared connections[].key \u2014 declare it: connections: [{ key: '${key}', integrationType: '<catalog slug, e.g. github>' }] and it resolves on any agent`;
|
|
2102
|
+
}
|
|
1941
2103
|
function classifyModelProvider(model) {
|
|
1942
2104
|
const m = (model ?? "").trim().toLowerCase();
|
|
1943
2105
|
if (!m) return null;
|
|
@@ -2040,6 +2202,33 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2040
2202
|
if (envelopeWorkspace?.backend && envelopeWorkspace.backend !== "ebs" && opts.policy?.workspaceBackends && !opts.policy.workspaceBackends.includes(envelopeWorkspace.backend)) {
|
|
2041
2203
|
err("workspace-backend-unavailable", `workspace.backend '${envelopeWorkspace.backend}' is not enabled (LUA_WF_WORKSPACE_BACKENDS = ${opts.policy.workspaceBackends.join(",")}) \u2014 'ebs' is the normative fallback`, "workspace.backend");
|
|
2042
2204
|
}
|
|
2205
|
+
const declaredKeys = new Set(opts.connectionKeys ?? []);
|
|
2206
|
+
if (g.connections !== void 0 && !Array.isArray(g.connections)) {
|
|
2207
|
+
err("connection-declaration-invalid", "`connections` must be an array of { key, integrationType }", "connections");
|
|
2208
|
+
}
|
|
2209
|
+
(Array.isArray(g.connections) ? g.connections : []).forEach((c, i) => {
|
|
2210
|
+
const path3 = `connections.${i}`;
|
|
2211
|
+
const key = c?.key;
|
|
2212
|
+
const integrationType = c?.integrationType;
|
|
2213
|
+
if (typeof key !== "string" || !WORKFLOW_CONNECTION_KEY_RE.test(key)) {
|
|
2214
|
+
err("connection-declaration-invalid", `connections[${i}].key must match ${WORKFLOW_CONNECTION_KEY_RE}`, `${path3}.key`);
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
if (declaredKeys.has(key)) {
|
|
2218
|
+
err("connection-declaration-invalid", `connections[${i}].key "${key}" is declared twice`, `${path3}.key`);
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
if (typeof integrationType !== "string" || !integrationType.trim()) {
|
|
2222
|
+
err("connection-declaration-invalid", `connections[${i}] ("${key}") needs an integrationType (the catalog slug, e.g. 'github')`, `${path3}.integrationType`);
|
|
2223
|
+
return;
|
|
2224
|
+
}
|
|
2225
|
+
declaredKeys.add(key);
|
|
2226
|
+
});
|
|
2227
|
+
const undeclaredKey = /* @__PURE__ */ __name3((ref) => typeof ref === "string" && !declaredKeys.has(ref) && isConnectionKeyShaped(ref) && opts.connectionIds?.has(ref) !== true, "undeclaredKey");
|
|
2228
|
+
const credentialsRef = envelopeWorkspace?.credentialsRef;
|
|
2229
|
+
if (undeclaredKey(credentialsRef)) {
|
|
2230
|
+
err("connection-key-undeclared", connectionKeyUndeclaredMessage("workspace.credentialsRef", credentialsRef), "workspace.credentialsRef");
|
|
2231
|
+
}
|
|
2043
2232
|
const seen = /* @__PURE__ */ new Map();
|
|
2044
2233
|
let nodeCount = 0;
|
|
2045
2234
|
const upstream = /* @__PURE__ */ new Set();
|
|
@@ -2051,6 +2240,16 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2051
2240
|
seen.set(id, path3);
|
|
2052
2241
|
}
|
|
2053
2242
|
}, "checkId");
|
|
2243
|
+
const checkPolicyEnums = /* @__PURE__ */ __name3((node, path3) => {
|
|
2244
|
+
const id = singleId(node);
|
|
2245
|
+
const check = /* @__PURE__ */ __name3((member, allowed) => {
|
|
2246
|
+
const value22 = node[member];
|
|
2247
|
+
if (value22 === void 0 || typeof value22 === "string" && allowed.includes(value22)) return;
|
|
2248
|
+
err("invalid-envelope", `\`${member}\` must be ${allowed.map((a) => `'${a}'`).join(" | ")} (got ${JSON.stringify(value22)})`, `${path3}.${member}`, id);
|
|
2249
|
+
}, "check");
|
|
2250
|
+
check("sideEffects", WORKFLOW_SIDE_EFFECTS);
|
|
2251
|
+
check("jobResources", WORKFLOW_JOB_RESOURCES);
|
|
2252
|
+
}, "checkPolicyEnums");
|
|
2054
2253
|
const checkRetry = /* @__PURE__ */ __name3((node, path3) => {
|
|
2055
2254
|
const r = node.retry;
|
|
2056
2255
|
if (!r) return;
|
|
@@ -2058,6 +2257,9 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2058
2257
|
if (r.backoff !== void 0 && r.backoff !== "fixed" && r.backoff !== "exponential") {
|
|
2059
2258
|
err("backoff-invalid", `retry.backoff must be 'fixed' | 'exponential'`, `${path3}.retry.backoff`, id);
|
|
2060
2259
|
}
|
|
2260
|
+
if (r.backoffSeconds !== void 0 && r.backoffSeconds < 0) {
|
|
2261
|
+
err("backoff-invalid", "retry.backoffSeconds must be \u2265 0", `${path3}.retry.backoffSeconds`, id);
|
|
2262
|
+
}
|
|
2061
2263
|
if (r.maxBackoffSeconds !== void 0) {
|
|
2062
2264
|
if (r.backoff !== "exponential") {
|
|
2063
2265
|
err("backoff-invalid", "retry.maxBackoffSeconds is only meaningful with backoff:'exponential'", `${path3}.retry`, id);
|
|
@@ -2119,10 +2321,15 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2119
2321
|
}, "checkSpecialistRole");
|
|
2120
2322
|
const checkRequiredConnections = /* @__PURE__ */ __name3((node, path3) => {
|
|
2121
2323
|
const required = node.requiredConnections;
|
|
2122
|
-
if (!Array.isArray(required)
|
|
2123
|
-
const
|
|
2324
|
+
if (!Array.isArray(required)) return;
|
|
2325
|
+
const undeclared = required.filter(undeclaredKey);
|
|
2326
|
+
if (undeclared.length) {
|
|
2327
|
+
err("connection-key-undeclared", connectionKeyUndeclaredMessage(`${path3}.requiredConnections`, undeclared[0]) + (undeclared.length > 1 ? ` (also undeclared: ${JSON.stringify(undeclared.slice(1))})` : ""), `${path3}.requiredConnections`, singleId(node));
|
|
2328
|
+
}
|
|
2329
|
+
if (!opts.connectionIds) return;
|
|
2330
|
+
const unknown = required.filter((c) => typeof c !== "string" || !declaredKeys.has(c) && !opts.connectionIds.has(c));
|
|
2124
2331
|
if (unknown.length) {
|
|
2125
|
-
err("required-connection-unknown", `requiredConnections ${JSON.stringify(unknown)} are
|
|
2332
|
+
err("required-connection-unknown", `requiredConnections ${JSON.stringify(unknown)} are neither declared connections[].key values nor connections the owner can mount`, `${path3}.requiredConnections`, singleId(node));
|
|
2126
2333
|
}
|
|
2127
2334
|
}, "checkRequiredConnections");
|
|
2128
2335
|
const checkTier = /* @__PURE__ */ __name3((node, path3) => {
|
|
@@ -2208,6 +2415,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2208
2415
|
return;
|
|
2209
2416
|
}
|
|
2210
2417
|
checkId(singleId(node), path3);
|
|
2418
|
+
checkPolicyEnums(node, path3);
|
|
2211
2419
|
checkTimeout(node, path3);
|
|
2212
2420
|
checkTier(node, path3);
|
|
2213
2421
|
checkRetry(node, path3);
|
|
@@ -2274,6 +2482,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2274
2482
|
case "sleepUntil": {
|
|
2275
2483
|
const s = entry;
|
|
2276
2484
|
checkId(s.id, path3);
|
|
2485
|
+
err("node-type-unsupported-by-engine", sleepUntilUnsupportedMessage(s.id), path3, s.id);
|
|
2277
2486
|
if (s.date === void 0 === (s.dateFrom === void 0)) {
|
|
2278
2487
|
err("invalid-envelope", "sleepUntil needs exactly one of `date` | `dateFrom`", path3, s.id);
|
|
2279
2488
|
}
|
|
@@ -2319,7 +2528,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2319
2528
|
err("invalid-envelope", "conditional.predicates must match conditional.steps one-to-one", path3);
|
|
2320
2529
|
}
|
|
2321
2530
|
(c.predicates ?? []).forEach((p, j) => {
|
|
2322
|
-
if (!
|
|
2531
|
+
if (!isWellFormedPredicate(p)) err("closure-predicate", "a conditional predicate must be a well-formed LuaPredicate object ({op, left/right | value | path | args | arg}), not a function or an expression string", `${path3}.predicates.${j}`);
|
|
2323
2532
|
});
|
|
2324
2533
|
c.steps.forEach((arm, j) => {
|
|
2325
2534
|
checkArm(arm, `${path3}.steps.${j}`, 1);
|
|
@@ -2399,7 +2608,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2399
2608
|
if (l.intervalSeconds !== void 0 && (!Number.isInteger(l.intervalSeconds) || l.intervalSeconds < 1 || l.intervalSeconds > caps.maxLoopIntervalSeconds)) {
|
|
2400
2609
|
err("loop-interval-out-of-range", `loop.intervalSeconds must be an integer in 1..${caps.maxLoopIntervalSeconds}`, `${path3}.intervalSeconds`);
|
|
2401
2610
|
}
|
|
2402
|
-
if (!
|
|
2611
|
+
if (!isWellFormedPredicate(l.predicate)) err("closure-predicate", "a loop predicate must be a well-formed LuaPredicate object ({op, left/right | value | path | args | arg}), not a function or an expression string", `${path3}.predicate`);
|
|
2403
2612
|
const bodyType = l.step.type;
|
|
2404
2613
|
if (bodyType === "mapping") err("container-arm-empty", "a loop body needs a step, not a bare mapping", `${path3}.step`);
|
|
2405
2614
|
else if (bodyType === "approval" || bodyType === "waitForSignal") err("approval-inside-container", "approval / waitForSignal are top-level only in v1", `${path3}.step`);
|
|
@@ -2462,6 +2671,41 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
2462
2671
|
function isPredicate(p) {
|
|
2463
2672
|
return typeof p === "object" && p !== null && typeof p.op === "string" && PREDICATE_OPS.has(p.op);
|
|
2464
2673
|
}
|
|
2674
|
+
function isPathOrLiteral(v) {
|
|
2675
|
+
if (typeof v !== "object" || v === null) return false;
|
|
2676
|
+
const r = v;
|
|
2677
|
+
if ("path" in r) return typeof r.path === "string" && r.path.length > 0;
|
|
2678
|
+
return "literal" in r && isPredicateScalar(r.literal);
|
|
2679
|
+
}
|
|
2680
|
+
function isWellFormedPredicate(p) {
|
|
2681
|
+
if (!isPredicate(p)) return false;
|
|
2682
|
+
const r = p;
|
|
2683
|
+
switch (r.op) {
|
|
2684
|
+
case "eq":
|
|
2685
|
+
case "ne":
|
|
2686
|
+
case "lt":
|
|
2687
|
+
case "lte":
|
|
2688
|
+
case "gt":
|
|
2689
|
+
case "gte":
|
|
2690
|
+
return isPathOrLiteral(r.left) && isPathOrLiteral(r.right);
|
|
2691
|
+
case "in":
|
|
2692
|
+
case "notIn":
|
|
2693
|
+
return isPathOrLiteral(r.value) && Array.isArray(r.set) && r.set.every(isPredicateScalar);
|
|
2694
|
+
case "exists":
|
|
2695
|
+
case "notExists":
|
|
2696
|
+
return typeof r.path === "string" && r.path.length > 0;
|
|
2697
|
+
case "truthy":
|
|
2698
|
+
case "falsy":
|
|
2699
|
+
return isPathOrLiteral(r.value);
|
|
2700
|
+
case "and":
|
|
2701
|
+
case "or":
|
|
2702
|
+
return Array.isArray(r.args) && r.args.every(isWellFormedPredicate);
|
|
2703
|
+
case "not":
|
|
2704
|
+
return isWellFormedPredicate(r.arg);
|
|
2705
|
+
default:
|
|
2706
|
+
return false;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2465
2709
|
function canonicalJson(value22) {
|
|
2466
2710
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
2467
2711
|
const encode = /* @__PURE__ */ __name3((v) => {
|
|
@@ -3024,6 +3268,25 @@ function resolveMapping(cfg, ctx) {
|
|
|
3024
3268
|
value: result
|
|
3025
3269
|
};
|
|
3026
3270
|
}
|
|
3271
|
+
function continuedFailureValue(error, killReason) {
|
|
3272
|
+
const code = typeof error?.code === "string" && error.code || typeof killReason === "string" && killReason || CONTINUED_FAILURE_DEFAULT_CODE;
|
|
3273
|
+
const message = typeof error?.message === "string" && error.message ? error.message : code;
|
|
3274
|
+
return {
|
|
3275
|
+
__lua_workflow: CONTINUED_FAILURE_TAG,
|
|
3276
|
+
failed: true,
|
|
3277
|
+
error: {
|
|
3278
|
+
code,
|
|
3279
|
+
message
|
|
3280
|
+
},
|
|
3281
|
+
text: ""
|
|
3282
|
+
};
|
|
3283
|
+
}
|
|
3284
|
+
function isContinuedFailureValue(v) {
|
|
3285
|
+
if (v === null || typeof v !== "object" || Array.isArray(v)) return false;
|
|
3286
|
+
const o = v;
|
|
3287
|
+
const err = o.error;
|
|
3288
|
+
return o.__lua_workflow === CONTINUED_FAILURE_TAG && o.failed === true && o.text === "" && err !== null && typeof err === "object" && typeof err.code === "string" && typeof err.message === "string";
|
|
3289
|
+
}
|
|
3027
3290
|
function lowerContainerArm(mapping, step22) {
|
|
3028
3291
|
const stepId = nodeIdOf(step22);
|
|
3029
3292
|
return {
|
|
@@ -3121,7 +3384,7 @@ function resolvePlacements(calls) {
|
|
|
3121
3384
|
if (!d) {
|
|
3122
3385
|
issues.push({
|
|
3123
3386
|
code: "unknown-step-ref",
|
|
3124
|
-
message: `"${ref.ref}" is not declared anywhere in the chain \u2014 declare it with agentStep/specialistStep/toolStep/map(\u2026, { id })`,
|
|
3387
|
+
message: `"${ref.ref}" is not declared anywhere in the chain \u2014 declare it with agentStep/specialistStep/toolStep/map(\u2026, { id })/workflow(\u2026)`,
|
|
3125
3388
|
callIndex: i,
|
|
3126
3389
|
stepId: ref.ref
|
|
3127
3390
|
});
|
|
@@ -3173,9 +3436,9 @@ function resolvePlacements(calls) {
|
|
|
3173
3436
|
});
|
|
3174
3437
|
const graph = [];
|
|
3175
3438
|
const lookup = /* @__PURE__ */ __name3((ref) => {
|
|
3176
|
-
const
|
|
3177
|
-
if (!
|
|
3178
|
-
return lowerContainerArm(ref.armMap,
|
|
3439
|
+
const n2 = "node" in ref ? ref.node : declared.get(ref.ref)?.node;
|
|
3440
|
+
if (!n2 || !ref.armMap || n2.type === "mapping") return n2;
|
|
3441
|
+
return lowerContainerArm(ref.armMap, n2);
|
|
3179
3442
|
}, "lookup");
|
|
3180
3443
|
calls.forEach((call, i) => {
|
|
3181
3444
|
switch (call.kind) {
|
|
@@ -3194,7 +3457,7 @@ function resolvePlacements(calls) {
|
|
|
3194
3457
|
return;
|
|
3195
3458
|
}
|
|
3196
3459
|
case "parallel": {
|
|
3197
|
-
const steps = call.arms.map(lookup).filter((
|
|
3460
|
+
const steps = call.arms.map(lookup).filter((n2) => !!n2 && n2.type !== "mapping");
|
|
3198
3461
|
const node = {
|
|
3199
3462
|
type: "parallel",
|
|
3200
3463
|
steps
|
|
@@ -3207,9 +3470,9 @@ function resolvePlacements(calls) {
|
|
|
3207
3470
|
const steps = [];
|
|
3208
3471
|
const predicates = [];
|
|
3209
3472
|
for (const a of call.arms) {
|
|
3210
|
-
const
|
|
3211
|
-
if (!
|
|
3212
|
-
steps.push(
|
|
3473
|
+
const n2 = lookup(a.target);
|
|
3474
|
+
if (!n2) continue;
|
|
3475
|
+
steps.push(n2);
|
|
3213
3476
|
predicates.push(a.predicate);
|
|
3214
3477
|
}
|
|
3215
3478
|
const node = {
|
|
@@ -3313,31 +3576,54 @@ function seedLedgerFromRun(run, steps, targetPlan, opts = {}) {
|
|
|
3313
3576
|
graphChanged
|
|
3314
3577
|
};
|
|
3315
3578
|
}
|
|
3579
|
+
function branchSpecFromConditional(entry) {
|
|
3580
|
+
return {
|
|
3581
|
+
arms: entry.steps.map((arm, i) => ({
|
|
3582
|
+
stepId: branchArmId(arm),
|
|
3583
|
+
predicate: entry.predicates[i]
|
|
3584
|
+
})),
|
|
3585
|
+
...entry.exclusive === true ? {
|
|
3586
|
+
exclusive: true
|
|
3587
|
+
} : {},
|
|
3588
|
+
...entry.otherwise ? {
|
|
3589
|
+
otherwise: branchArmId(entry.otherwise)
|
|
3590
|
+
} : {}
|
|
3591
|
+
};
|
|
3592
|
+
}
|
|
3593
|
+
function selectBranchArms(spec, ctx) {
|
|
3594
|
+
const taken = [];
|
|
3595
|
+
for (const arm of spec.arms) {
|
|
3596
|
+
if (spec.exclusive && taken.length > 0) break;
|
|
3597
|
+
const hit = arm.predicate ? evaluatePredicate(arm.predicate, ctx) : false;
|
|
3598
|
+
if (hit) taken.push(arm.stepId);
|
|
3599
|
+
}
|
|
3600
|
+
if (taken.length === 0 && spec.otherwise) taken.push(spec.otherwise);
|
|
3601
|
+
return taken;
|
|
3602
|
+
}
|
|
3316
3603
|
function replayLedger(g, ledger) {
|
|
3317
3604
|
const plan = compilePlan(g);
|
|
3318
3605
|
const rows22 = new Map(ledger.steps.map((r) => [
|
|
3319
3606
|
r.stepId,
|
|
3320
3607
|
r
|
|
3321
3608
|
]));
|
|
3322
|
-
const
|
|
3323
|
-
|
|
3324
|
-
|
|
3609
|
+
const requestContext = {
|
|
3610
|
+
runId: "replay",
|
|
3611
|
+
workflowId: g.definition.id,
|
|
3612
|
+
orgId: "",
|
|
3613
|
+
agentId: "",
|
|
3614
|
+
userId: "",
|
|
3615
|
+
trigger: "sdk",
|
|
3616
|
+
threadId: "replay",
|
|
3617
|
+
depth: 0,
|
|
3618
|
+
startedAt: 0,
|
|
3619
|
+
...ledger.requestContext
|
|
3620
|
+
};
|
|
3621
|
+
const ctxFor = /* @__PURE__ */ __name3((id) => ({
|
|
3325
3622
|
initData: ledger.initData,
|
|
3326
|
-
stepResults,
|
|
3623
|
+
stepResults: ancestorResults(plan, id, rows22),
|
|
3327
3624
|
state: ledger.state ?? {},
|
|
3328
|
-
requestContext
|
|
3329
|
-
|
|
3330
|
-
workflowId: g.definition.id,
|
|
3331
|
-
orgId: "",
|
|
3332
|
-
agentId: "",
|
|
3333
|
-
userId: "",
|
|
3334
|
-
trigger: "sdk",
|
|
3335
|
-
threadId: "replay",
|
|
3336
|
-
depth: 0,
|
|
3337
|
-
startedAt: 0,
|
|
3338
|
-
...ledger.requestContext
|
|
3339
|
-
}
|
|
3340
|
-
};
|
|
3625
|
+
requestContext
|
|
3626
|
+
}), "ctxFor");
|
|
3341
3627
|
const verdicts = [];
|
|
3342
3628
|
for (const id of plan.order) {
|
|
3343
3629
|
const node = plan.steps[id];
|
|
@@ -3345,17 +3631,7 @@ function replayLedger(g, ledger) {
|
|
|
3345
3631
|
if (!recorded || recorded.status === "pending" || recorded.status === "skipped") continue;
|
|
3346
3632
|
if (node.kind === "branch") {
|
|
3347
3633
|
const entry = node.entry;
|
|
3348
|
-
const taken =
|
|
3349
|
-
entry.steps.forEach((arm, i) => {
|
|
3350
|
-
const pred = entry.predicates[i];
|
|
3351
|
-
const hit = pred ? evaluatePredicate(pred, {
|
|
3352
|
-
initData: ledger.initData,
|
|
3353
|
-
stepResults,
|
|
3354
|
-
state: ledger.state
|
|
3355
|
-
}) : false;
|
|
3356
|
-
if (hit && (!entry.exclusive || taken.length === 0)) taken.push(armId2(arm));
|
|
3357
|
-
});
|
|
3358
|
-
if (taken.length === 0 && entry.otherwise) taken.push(armId2(entry.otherwise));
|
|
3634
|
+
const taken = selectBranchArms(branchSpecFromConditional(entry), ctxFor(id));
|
|
3359
3635
|
const recordedTaken = recorded.taken ?? inferTaken(entry, rows22);
|
|
3360
3636
|
verdicts.push({
|
|
3361
3637
|
stepId: id,
|
|
@@ -3366,7 +3642,7 @@ function replayLedger(g, ledger) {
|
|
|
3366
3642
|
});
|
|
3367
3643
|
} else if (node.kind === "map" && !id.endsWith(".join") && recorded.status === "completed") {
|
|
3368
3644
|
const entry = node.entry;
|
|
3369
|
-
const resolved = resolveMapping(parseMapConfig(entry.mapConfig, id),
|
|
3645
|
+
const resolved = resolveMapping(parseMapConfig(entry.mapConfig, id), ctxFor(id));
|
|
3370
3646
|
const local = "error" in resolved ? {
|
|
3371
3647
|
error: resolved.error,
|
|
3372
3648
|
key: resolved.key
|
|
@@ -3381,7 +3657,7 @@ function replayLedger(g, ledger) {
|
|
|
3381
3657
|
} else if (node.kind === "foreach") {
|
|
3382
3658
|
const entry = node.entry;
|
|
3383
3659
|
const source = node.dependsOn[0];
|
|
3384
|
-
const items = source ? stepResults[source] : void 0;
|
|
3660
|
+
const items = source ? ctxFor(id).stepResults[source] : void 0;
|
|
3385
3661
|
const local = Array.isArray(items) ? items.length : void 0;
|
|
3386
3662
|
const recordedCount = recorded.itemCount ?? countChildren(entry, rows22);
|
|
3387
3663
|
verdicts.push({
|
|
@@ -3398,6 +3674,71 @@ function replayLedger(g, ledger) {
|
|
|
3398
3674
|
diverged: verdicts.some((v) => v.diverged)
|
|
3399
3675
|
};
|
|
3400
3676
|
}
|
|
3677
|
+
function replayResultOf(row, node) {
|
|
3678
|
+
if (!row) return void 0;
|
|
3679
|
+
if (row.status === "completed") return {
|
|
3680
|
+
value: row.output
|
|
3681
|
+
};
|
|
3682
|
+
if (row.status === "failed") {
|
|
3683
|
+
const onError = row.onError ?? node?.entry?.onError;
|
|
3684
|
+
if (onError === "continue") return {
|
|
3685
|
+
value: continuedFailureValue(row.error, row.killReason)
|
|
3686
|
+
};
|
|
3687
|
+
}
|
|
3688
|
+
return void 0;
|
|
3689
|
+
}
|
|
3690
|
+
function ancestorResults(plan, id, rows22) {
|
|
3691
|
+
const out = {};
|
|
3692
|
+
const joinAliased = /* @__PURE__ */ new Set();
|
|
3693
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3694
|
+
const take = /* @__PURE__ */ __name3((rowId) => {
|
|
3695
|
+
const hit = replayResultOf(rows22.get(rowId), plan.steps[rowId]);
|
|
3696
|
+
if (!hit) return void 0;
|
|
3697
|
+
if (!joinAliased.has(rowId)) out[rowId] = hit.value;
|
|
3698
|
+
const entryId = entryOfJoin(rowId);
|
|
3699
|
+
if (entryId) {
|
|
3700
|
+
out[entryId] = hit.value;
|
|
3701
|
+
joinAliased.add(entryId);
|
|
3702
|
+
const entryNode = plan.steps[entryId];
|
|
3703
|
+
if (entryNode?.kind === "foreach") {
|
|
3704
|
+
const body = branchArmId(entryNode.entry.step);
|
|
3705
|
+
out[body] = hit.value;
|
|
3706
|
+
joinAliased.add(body);
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
return hit;
|
|
3710
|
+
}, "take");
|
|
3711
|
+
const walk2 = /* @__PURE__ */ __name3((ids) => {
|
|
3712
|
+
for (const dep of ids) {
|
|
3713
|
+
if (seen.has(dep)) continue;
|
|
3714
|
+
seen.add(dep);
|
|
3715
|
+
take(dep);
|
|
3716
|
+
const node = plan.steps[dep] ?? plan.steps[entryOfJoin(dep) ?? ""];
|
|
3717
|
+
if (!node) continue;
|
|
3718
|
+
if (node.kind === "foreach") {
|
|
3719
|
+
const body = branchArmId(node.entry.step);
|
|
3720
|
+
for (const rowId of rows22.keys()) if (rowId.startsWith(`${body}[`)) take(rowId);
|
|
3721
|
+
} else if (node.kind === "loop") {
|
|
3722
|
+
const body = branchArmId(node.entry.step);
|
|
3723
|
+
let best = -1;
|
|
3724
|
+
for (const rowId of rows22.keys()) {
|
|
3725
|
+
if (!rowId.startsWith(`${body}#`)) continue;
|
|
3726
|
+
const n2 = Number(rowId.slice(body.length + 1));
|
|
3727
|
+
if (!Number.isInteger(n2)) continue;
|
|
3728
|
+
const hit = take(rowId);
|
|
3729
|
+
if (!hit) continue;
|
|
3730
|
+
if (n2 > best) {
|
|
3731
|
+
best = n2;
|
|
3732
|
+
out[body] = hit.value;
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
walk2(node.dependsOn);
|
|
3737
|
+
}
|
|
3738
|
+
}, "walk");
|
|
3739
|
+
walk2(plan.steps[id]?.dependsOn ?? []);
|
|
3740
|
+
return out;
|
|
3741
|
+
}
|
|
3401
3742
|
function inferTaken(entry, rows22) {
|
|
3402
3743
|
const arms = [
|
|
3403
3744
|
...entry.steps,
|
|
@@ -3405,16 +3746,16 @@ function inferTaken(entry, rows22) {
|
|
|
3405
3746
|
entry.otherwise
|
|
3406
3747
|
] : []
|
|
3407
3748
|
];
|
|
3408
|
-
return arms.map(
|
|
3749
|
+
return arms.map(branchArmId).filter((id) => {
|
|
3409
3750
|
const r = rows22.get(id);
|
|
3410
3751
|
return r !== void 0 && r.status !== "skipped" && r.status !== "pending";
|
|
3411
3752
|
});
|
|
3412
3753
|
}
|
|
3413
3754
|
function countChildren(entry, rows22) {
|
|
3414
|
-
const body =
|
|
3415
|
-
let
|
|
3416
|
-
for (const id of rows22.keys()) if (id.startsWith(`${body}[`))
|
|
3417
|
-
return
|
|
3755
|
+
const body = branchArmId(entry.step);
|
|
3756
|
+
let n2 = 0;
|
|
3757
|
+
for (const id of rows22.keys()) if (id.startsWith(`${body}[`)) n2 += 1;
|
|
3758
|
+
return n2;
|
|
3418
3759
|
}
|
|
3419
3760
|
function isTerminalRunStatus(status) {
|
|
3420
3761
|
return TERMINAL.has(status);
|
|
@@ -3423,19 +3764,48 @@ function pruneUndefined(o) {
|
|
|
3423
3764
|
return Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
3424
3765
|
}
|
|
3425
3766
|
function runNextAction(run) {
|
|
3426
|
-
if (isTerminalRunStatus(run.status)
|
|
3767
|
+
if (isTerminalRunStatus(run.status)) return "none";
|
|
3768
|
+
if (run.status === "suspended" && run.gate?.kind === "budget") return "raise_budget";
|
|
3769
|
+
if (!run.cancel?.requestedAt) return "none";
|
|
3427
3770
|
const forceAt = run.cancel.forceAfter ?? run.cancel.requestedAt + FORCE_CANCEL_STALE_MS;
|
|
3428
3771
|
return Date.now() >= forceAt ? "force" : "cancel_again";
|
|
3429
3772
|
}
|
|
3773
|
+
function emptyRunCounts() {
|
|
3774
|
+
const out = {
|
|
3775
|
+
total: 0,
|
|
3776
|
+
inFlight: 0
|
|
3777
|
+
};
|
|
3778
|
+
for (const status of WORKFLOW_STEP_STATUSES) out[status] = 0;
|
|
3779
|
+
return out;
|
|
3780
|
+
}
|
|
3781
|
+
function runCountsFromStatusTally(tally) {
|
|
3782
|
+
const out = emptyRunCounts();
|
|
3783
|
+
for (const [status, n2] of Object.entries(tally)) {
|
|
3784
|
+
if (!Number.isFinite(n2) || n2 <= 0) continue;
|
|
3785
|
+
out.total += n2;
|
|
3786
|
+
if (WORKFLOW_STEP_STATUSES.includes(status)) out[status] += n2;
|
|
3787
|
+
if (IN_FLIGHT.has(status)) out.inFlight += n2;
|
|
3788
|
+
}
|
|
3789
|
+
return out;
|
|
3790
|
+
}
|
|
3791
|
+
function runCountsFromStepStatuses(statuses) {
|
|
3792
|
+
const tally = {};
|
|
3793
|
+
for (const s of statuses) tally[s] = (tally[s] ?? 0) + 1;
|
|
3794
|
+
return runCountsFromStatusTally(tally);
|
|
3795
|
+
}
|
|
3430
3796
|
function runCounts(counts) {
|
|
3797
|
+
const c = counts ?? {};
|
|
3798
|
+
const rawInFlight = c.dispatched !== void 0 || c.claimed !== void 0 || c.running !== void 0 || c.cancellation_requested !== void 0;
|
|
3431
3799
|
return {
|
|
3432
|
-
total:
|
|
3433
|
-
completed:
|
|
3434
|
-
failed:
|
|
3435
|
-
skipped:
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3800
|
+
total: n(c.total),
|
|
3801
|
+
completed: n(c.completed),
|
|
3802
|
+
failed: n(c.failed) + n(c.timeout) + n(c.reaped),
|
|
3803
|
+
skipped: n(c.skipped),
|
|
3804
|
+
// LUA-664: cancelled rows never ran — their own wire bucket, never a failure (the detail's map, verbatim).
|
|
3805
|
+
cancelled: n(c.cancelled),
|
|
3806
|
+
running: rawInFlight ? n(c.dispatched) + n(c.claimed) + n(c.running) + n(c.cancellation_requested) : n(c.inFlight),
|
|
3807
|
+
suspended: n(c.suspended),
|
|
3808
|
+
pending: n(c.pending) + n(c.ready) + n(c.waiting)
|
|
3439
3809
|
};
|
|
3440
3810
|
}
|
|
3441
3811
|
function runUsage(run) {
|
|
@@ -3459,7 +3829,7 @@ function runWorkspaceView(ws) {
|
|
|
3459
3829
|
if (!ws) return void 0;
|
|
3460
3830
|
const w = ws;
|
|
3461
3831
|
return pruneUndefined({
|
|
3462
|
-
kind: w.kind ?? "empty",
|
|
3832
|
+
kind: w.spec?.kind ?? w.kind ?? "empty",
|
|
3463
3833
|
backend: w.backend,
|
|
3464
3834
|
status: String(w.status ?? ""),
|
|
3465
3835
|
branch: w.branch,
|
|
@@ -3521,7 +3891,10 @@ function toWorkflowRunSummary(run) {
|
|
|
3521
3891
|
eventSeq: run.eventSeq ?? 0,
|
|
3522
3892
|
cancellable: !isTerminalRunStatus(status),
|
|
3523
3893
|
nextAction: runNextAction(run),
|
|
3524
|
-
workspace: runWorkspaceView(run.workspace)
|
|
3894
|
+
workspace: runWorkspaceView(run.workspace),
|
|
3895
|
+
// LUA-643: the runs list says a result exists; R4 `fields:'full'` (output-ACL gated, audited) serves it. The
|
|
3896
|
+
// stamped flag is what a list page carries (it projects `output` out); the payload members cover R4's full row.
|
|
3897
|
+
hasOutput: run.hasOutput === true || run.output !== void 0 || run.outputRef !== void 0 ? true : void 0
|
|
3525
3898
|
});
|
|
3526
3899
|
}
|
|
3527
3900
|
function timeZoneSupported(tz) {
|
|
@@ -4216,8 +4589,8 @@ function armEntry(arm) {
|
|
|
4216
4589
|
}
|
|
4217
4590
|
function ofEntry(e) {
|
|
4218
4591
|
if (!e || typeof e !== "object") return ZERO;
|
|
4219
|
-
const
|
|
4220
|
-
switch (
|
|
4592
|
+
const n2 = e;
|
|
4593
|
+
switch (n2.type) {
|
|
4221
4594
|
case "agent":
|
|
4222
4595
|
return {
|
|
4223
4596
|
steps: {
|
|
@@ -4250,17 +4623,17 @@ function ofEntry(e) {
|
|
|
4250
4623
|
agentCalls: 0
|
|
4251
4624
|
};
|
|
4252
4625
|
case "parallel": {
|
|
4253
|
-
const arms = Array.isArray(
|
|
4626
|
+
const arms = Array.isArray(n2.steps) ? n2.steps : [];
|
|
4254
4627
|
return arms.map(armEntry).map(ofEntry).reduce(add, ZERO);
|
|
4255
4628
|
}
|
|
4256
4629
|
case "conditional": {
|
|
4257
|
-
const arms = (Array.isArray(
|
|
4630
|
+
const arms = (Array.isArray(n2.steps) ? n2.steps : []).map(armEntry).map(ofEntry);
|
|
4258
4631
|
if (arms.length === 0) return ZERO;
|
|
4259
|
-
const hasOtherwise =
|
|
4632
|
+
const hasOtherwise = n2.otherwise !== void 0;
|
|
4260
4633
|
const minArm = arms.reduce((a, b) => b.credits.min < a.credits.min ? b : a);
|
|
4261
4634
|
const maxArm = arms.reduce((a, b) => b.credits.max > a.credits.max ? b : a);
|
|
4262
4635
|
const summed = arms.reduce(add, ZERO);
|
|
4263
|
-
const max =
|
|
4636
|
+
const max = n2.exclusive === true ? maxArm : summed;
|
|
4264
4637
|
const min = hasOtherwise ? minArm : {
|
|
4265
4638
|
...ZERO
|
|
4266
4639
|
};
|
|
@@ -4277,17 +4650,14 @@ function ofEntry(e) {
|
|
|
4277
4650
|
};
|
|
4278
4651
|
}
|
|
4279
4652
|
case "foreach": {
|
|
4280
|
-
const body = ofEntry(armEntry(
|
|
4281
|
-
const opts =
|
|
4282
|
-
const cap = typeof opts.maxItems === "number" && opts.maxItems > 0 ? opts.maxItems :
|
|
4653
|
+
const body = ofEntry(armEntry(n2.step));
|
|
4654
|
+
const opts = n2.opts ?? {};
|
|
4655
|
+
const cap = typeof opts.maxItems === "number" && opts.maxItems > 0 ? opts.maxItems : WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS;
|
|
4283
4656
|
return scale(body, 0, cap);
|
|
4284
4657
|
}
|
|
4285
|
-
case "loop":
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
const body = ofEntry(armEntry(n.step));
|
|
4289
|
-
const opts = n.options ?? {};
|
|
4290
|
-
const cap = typeof opts.maxIterations === "number" && opts.maxIterations > 0 ? opts.maxIterations : 1;
|
|
4658
|
+
case "loop": {
|
|
4659
|
+
const body = ofEntry(armEntry(n2.step));
|
|
4660
|
+
const cap = typeof n2.maxIterations === "number" && n2.maxIterations > 0 ? n2.maxIterations : WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS;
|
|
4291
4661
|
return scale(body, 1, cap);
|
|
4292
4662
|
}
|
|
4293
4663
|
default:
|
|
@@ -4318,14 +4688,84 @@ function estimateGraph(envelopeOrGraph) {
|
|
|
4318
4688
|
consentCredits: r.credits.max
|
|
4319
4689
|
};
|
|
4320
4690
|
}
|
|
4321
|
-
|
|
4691
|
+
function* singleStepsOf(entry) {
|
|
4692
|
+
if (!isRecord2(entry)) return;
|
|
4693
|
+
switch (entry.type) {
|
|
4694
|
+
case "step":
|
|
4695
|
+
case "agent":
|
|
4696
|
+
case "tool":
|
|
4697
|
+
yield entry;
|
|
4698
|
+
return;
|
|
4699
|
+
case "workflow":
|
|
4700
|
+
yield entry;
|
|
4701
|
+
if (Array.isArray(entry.graph)) yield* singleStepsOf(entry.graph[1]);
|
|
4702
|
+
return;
|
|
4703
|
+
case "parallel":
|
|
4704
|
+
case "conditional":
|
|
4705
|
+
if (Array.isArray(entry.steps)) for (const arm of entry.steps) yield* singleStepsOf(arm);
|
|
4706
|
+
yield* singleStepsOf(entry.otherwise);
|
|
4707
|
+
return;
|
|
4708
|
+
case "foreach":
|
|
4709
|
+
case "loop":
|
|
4710
|
+
yield* singleStepsOf(entry.step);
|
|
4711
|
+
return;
|
|
4712
|
+
default:
|
|
4713
|
+
return;
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
function entriesOf(graph) {
|
|
4717
|
+
const definition = isRecord2(graph) ? graph.definition : void 0;
|
|
4718
|
+
const entries = isRecord2(definition) ? definition.graph : void 0;
|
|
4719
|
+
return Array.isArray(entries) ? entries : [];
|
|
4720
|
+
}
|
|
4721
|
+
function inheritTargets(graphs) {
|
|
4722
|
+
const targets = /* @__PURE__ */ new Set();
|
|
4723
|
+
for (const graph of graphs) {
|
|
4724
|
+
for (const entry of entriesOf(graph)) {
|
|
4725
|
+
for (const node of singleStepsOf(entry)) {
|
|
4726
|
+
if (node.type === "workflow" && node.workspace === "inherit" && typeof node.workflowId === "string" && node.workflowId.length > 0) {
|
|
4727
|
+
targets.add(node.workflowId);
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
return targets;
|
|
4733
|
+
}
|
|
4734
|
+
function needsInheritedWorkspace(graph) {
|
|
4735
|
+
if (!isRecord2(graph) || graph.workspace !== void 0) return false;
|
|
4736
|
+
for (const entry of entriesOf(graph)) {
|
|
4737
|
+
for (const node of singleStepsOf(entry)) {
|
|
4738
|
+
if (node.workspace !== void 0 && node.workspace !== "inherit") return true;
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
return false;
|
|
4742
|
+
}
|
|
4743
|
+
var __defProp3, __name3, WORKFLOW_SIDE_EFFECTS, WORKFLOW_JOB_RESOURCES, SideEffectsSchema, JobResourcesSchema, WORKFLOW_ARM_SUBRUN_ID, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_TOOLS, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, SINGLE_STEP_KINDS, isSingleStep, singleStepId, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not, WorkflowTemplateError, TEMPLATE_PLACEHOLDER, TEMPLATE_NAMESPACES, fromInit, fromStep, value, template, fromRequest, rows, fromKnowledge, CONTINUED_FAILURE_TAG, CONTINUED_FAILURE_DEFAULT_CODE, CONTINUED_FAILURE_OUTPUT_SCHEMA, CONTINUED_FAILURE_LEAF_PATHS, nodeIdOf, branchArmId, canonical, sortKeys, JOIN, entryOfJoin, FORCE_CANCEL_STALE_MS, TERMINAL, IN_FLIGHT, n, MAX_HOLIDAYS, MAX_WALK_DAYS, HHMM, YMD, MS_PER_MIN, MS_PER_DAY, MON_FRI, supportedTz, fmtCache, WEEKDAYS, JSON_PATCH_OPS, JSON_PATCH_MAX_OPS, JSON_PATCH_MAX_VALUE_BYTES, JSON_PATCH_MAX_TOTAL_BYTES, SEGMENT_RE, APPROVER_SPEC_MAX_USERS, ESCALATION_MAX_HOPS, TemplateBindingSchema, ApproverSpecSchema, FourEyesSchema, EscalationHopSchema, TerminalOutcomeSchema, ApprovalOnTimeoutSchema, BINDING_ROOTS, WORKFLOW_ENV_OVERLAY_MAX_KEYS, WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES, WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE, isEnvRef, looksLikeEmbeddedJson, ZERO, isRecord2;
|
|
4322
4744
|
var init_dist2 = __esm({
|
|
4323
4745
|
"../workflow-graph/dist/index.mjs"() {
|
|
4324
4746
|
"use strict";
|
|
4325
4747
|
init_dist();
|
|
4748
|
+
init_dist();
|
|
4326
4749
|
__defProp3 = Object.defineProperty;
|
|
4327
4750
|
__name3 = /* @__PURE__ */ __name((target, value22) => __defProp3(target, "name", { value: value22, configurable: true }), "__name");
|
|
4751
|
+
WORKFLOW_SIDE_EFFECTS = [
|
|
4752
|
+
"none",
|
|
4753
|
+
"external"
|
|
4754
|
+
];
|
|
4755
|
+
WORKFLOW_JOB_RESOURCES = [
|
|
4756
|
+
"small",
|
|
4757
|
+
"medium",
|
|
4758
|
+
"large"
|
|
4759
|
+
];
|
|
4760
|
+
SideEffectsSchema = z4.enum(WORKFLOW_SIDE_EFFECTS);
|
|
4761
|
+
JobResourcesSchema = z4.enum(WORKFLOW_JOB_RESOURCES);
|
|
4328
4762
|
WORKFLOW_ARM_SUBRUN_ID = "$arm";
|
|
4763
|
+
SLEEP_UNTIL_REPLACEMENT = Object.freeze({
|
|
4764
|
+
type: "sleep",
|
|
4765
|
+
duration: 6e4
|
|
4766
|
+
});
|
|
4767
|
+
__name(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
|
|
4768
|
+
__name3(sleepUntilUnsupportedMessage, "sleepUntilUnsupportedMessage");
|
|
4329
4769
|
WORKFLOW_CAPS_DEFAULT = Object.freeze({
|
|
4330
4770
|
maxParallelArms: 16,
|
|
4331
4771
|
maxForeachConcurrency: 16,
|
|
@@ -4361,6 +4801,11 @@ var init_dist2 = __esm({
|
|
|
4361
4801
|
__name3(fillEntry, "fillEntry");
|
|
4362
4802
|
__name(withDefaultsFilled, "withDefaultsFilled");
|
|
4363
4803
|
__name3(withDefaultsFilled, "withDefaultsFilled");
|
|
4804
|
+
CONNECTION_ID_HEX_RE = /^[0-9a-f]{24}$/;
|
|
4805
|
+
__name(isConnectionKeyShaped, "isConnectionKeyShaped");
|
|
4806
|
+
__name3(isConnectionKeyShaped, "isConnectionKeyShaped");
|
|
4807
|
+
__name(connectionKeyUndeclaredMessage, "connectionKeyUndeclaredMessage");
|
|
4808
|
+
__name3(connectionKeyUndeclaredMessage, "connectionKeyUndeclaredMessage");
|
|
4364
4809
|
WORKFLOW_JOB_TOOLS = [
|
|
4365
4810
|
"shell",
|
|
4366
4811
|
"read",
|
|
@@ -4424,6 +4869,11 @@ var init_dist2 = __esm({
|
|
|
4424
4869
|
]);
|
|
4425
4870
|
__name(isPredicate, "isPredicate");
|
|
4426
4871
|
__name3(isPredicate, "isPredicate");
|
|
4872
|
+
isPredicateScalar = /* @__PURE__ */ __name3((v) => v === null || typeof v === "string" || typeof v === "number" || typeof v === "boolean", "isPredicateScalar");
|
|
4873
|
+
__name(isPathOrLiteral, "isPathOrLiteral");
|
|
4874
|
+
__name3(isPathOrLiteral, "isPathOrLiteral");
|
|
4875
|
+
__name(isWellFormedPredicate, "isWellFormedPredicate");
|
|
4876
|
+
__name3(isWellFormedPredicate, "isWellFormedPredicate");
|
|
4427
4877
|
GRAPH_HASH_PREFIX = "sha256-cj1:";
|
|
4428
4878
|
__name(canonicalJson, "canonicalJson");
|
|
4429
4879
|
__name3(canonicalJson, "canonicalJson");
|
|
@@ -4612,16 +5062,71 @@ var init_dist2 = __esm({
|
|
|
4612
5062
|
fromKnowledge = /* @__PURE__ */ __name3((k) => ({
|
|
4613
5063
|
knowledge: k
|
|
4614
5064
|
}), "fromKnowledge");
|
|
5065
|
+
CONTINUED_FAILURE_TAG = "continued_failure";
|
|
5066
|
+
CONTINUED_FAILURE_DEFAULT_CODE = "step_failed";
|
|
5067
|
+
CONTINUED_FAILURE_OUTPUT_SCHEMA = Object.freeze({
|
|
5068
|
+
type: "object",
|
|
5069
|
+
properties: {
|
|
5070
|
+
__lua_workflow: {
|
|
5071
|
+
type: "string",
|
|
5072
|
+
const: CONTINUED_FAILURE_TAG
|
|
5073
|
+
},
|
|
5074
|
+
failed: {
|
|
5075
|
+
type: "boolean",
|
|
5076
|
+
const: true
|
|
5077
|
+
},
|
|
5078
|
+
error: {
|
|
5079
|
+
type: "object",
|
|
5080
|
+
properties: {
|
|
5081
|
+
code: {
|
|
5082
|
+
type: "string"
|
|
5083
|
+
},
|
|
5084
|
+
message: {
|
|
5085
|
+
type: "string"
|
|
5086
|
+
}
|
|
5087
|
+
},
|
|
5088
|
+
required: [
|
|
5089
|
+
"code",
|
|
5090
|
+
"message"
|
|
5091
|
+
]
|
|
5092
|
+
},
|
|
5093
|
+
text: {
|
|
5094
|
+
type: "string",
|
|
5095
|
+
const: ""
|
|
5096
|
+
}
|
|
5097
|
+
},
|
|
5098
|
+
required: [
|
|
5099
|
+
"__lua_workflow",
|
|
5100
|
+
"failed",
|
|
5101
|
+
"error",
|
|
5102
|
+
"text"
|
|
5103
|
+
]
|
|
5104
|
+
});
|
|
5105
|
+
CONTINUED_FAILURE_LEAF_PATHS = Object.freeze([
|
|
5106
|
+
"failed",
|
|
5107
|
+
"error",
|
|
5108
|
+
"error.code",
|
|
5109
|
+
"error.message",
|
|
5110
|
+
"text"
|
|
5111
|
+
]);
|
|
5112
|
+
__name(continuedFailureValue, "continuedFailureValue");
|
|
5113
|
+
__name3(continuedFailureValue, "continuedFailureValue");
|
|
5114
|
+
__name(isContinuedFailureValue, "isContinuedFailureValue");
|
|
5115
|
+
__name3(isContinuedFailureValue, "isContinuedFailureValue");
|
|
4615
5116
|
__name(lowerContainerArm, "lowerContainerArm");
|
|
4616
5117
|
__name3(lowerContainerArm, "lowerContainerArm");
|
|
4617
|
-
nodeIdOf = /* @__PURE__ */ __name3((
|
|
5118
|
+
nodeIdOf = /* @__PURE__ */ __name3((n2) => n2.type === "step" ? n2.step.id : n2.id, "nodeIdOf");
|
|
4618
5119
|
__name(entryIds, "entryIds");
|
|
4619
5120
|
__name3(entryIds, "entryIds");
|
|
4620
5121
|
__name(resolvePlacements, "resolvePlacements");
|
|
4621
5122
|
__name3(resolvePlacements, "resolvePlacements");
|
|
4622
5123
|
__name(seedLedgerFromRun, "seedLedgerFromRun");
|
|
4623
5124
|
__name3(seedLedgerFromRun, "seedLedgerFromRun");
|
|
4624
|
-
|
|
5125
|
+
branchArmId = /* @__PURE__ */ __name3((arm) => arm.type === "step" ? arm.step.id : arm.id, "branchArmId");
|
|
5126
|
+
__name(branchSpecFromConditional, "branchSpecFromConditional");
|
|
5127
|
+
__name3(branchSpecFromConditional, "branchSpecFromConditional");
|
|
5128
|
+
__name(selectBranchArms, "selectBranchArms");
|
|
5129
|
+
__name3(selectBranchArms, "selectBranchArms");
|
|
4625
5130
|
canonical = /* @__PURE__ */ __name3((v) => JSON.stringify(sortKeys(v)), "canonical");
|
|
4626
5131
|
sortKeys = /* @__PURE__ */ __name3((v) => {
|
|
4627
5132
|
if (Array.isArray(v)) return v.map(sortKeys);
|
|
@@ -4635,6 +5140,12 @@ var init_dist2 = __esm({
|
|
|
4635
5140
|
}, "sortKeys");
|
|
4636
5141
|
__name(replayLedger, "replayLedger");
|
|
4637
5142
|
__name3(replayLedger, "replayLedger");
|
|
5143
|
+
JOIN = ".join";
|
|
5144
|
+
entryOfJoin = /* @__PURE__ */ __name3((id) => id.endsWith(JOIN) ? id.slice(0, -JOIN.length) : void 0, "entryOfJoin");
|
|
5145
|
+
__name(replayResultOf, "replayResultOf");
|
|
5146
|
+
__name3(replayResultOf, "replayResultOf");
|
|
5147
|
+
__name(ancestorResults, "ancestorResults");
|
|
5148
|
+
__name3(ancestorResults, "ancestorResults");
|
|
4638
5149
|
__name(inferTaken, "inferTaken");
|
|
4639
5150
|
__name3(inferTaken, "inferTaken");
|
|
4640
5151
|
__name(countChildren, "countChildren");
|
|
@@ -4647,6 +5158,14 @@ var init_dist2 = __esm({
|
|
|
4647
5158
|
__name3(pruneUndefined, "pruneUndefined");
|
|
4648
5159
|
__name(runNextAction, "runNextAction");
|
|
4649
5160
|
__name3(runNextAction, "runNextAction");
|
|
5161
|
+
IN_FLIGHT = new Set(WORKFLOW_STEP_IN_FLIGHT);
|
|
5162
|
+
__name(emptyRunCounts, "emptyRunCounts");
|
|
5163
|
+
__name3(emptyRunCounts, "emptyRunCounts");
|
|
5164
|
+
__name(runCountsFromStatusTally, "runCountsFromStatusTally");
|
|
5165
|
+
__name3(runCountsFromStatusTally, "runCountsFromStatusTally");
|
|
5166
|
+
__name(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
5167
|
+
__name3(runCountsFromStepStatuses, "runCountsFromStepStatuses");
|
|
5168
|
+
n = /* @__PURE__ */ __name3((v) => typeof v === "number" && Number.isFinite(v) ? v : 0, "n");
|
|
4650
5169
|
__name(runCounts, "runCounts");
|
|
4651
5170
|
__name3(runCounts, "runCounts");
|
|
4652
5171
|
__name(runUsage, "runUsage");
|
|
@@ -4750,54 +5269,54 @@ var init_dist2 = __esm({
|
|
|
4750
5269
|
__name3(rebaseItemPointer, "rebaseItemPointer");
|
|
4751
5270
|
APPROVER_SPEC_MAX_USERS = 20;
|
|
4752
5271
|
ESCALATION_MAX_HOPS = 3;
|
|
4753
|
-
TemplateBindingSchema =
|
|
4754
|
-
template:
|
|
5272
|
+
TemplateBindingSchema = z22.object({
|
|
5273
|
+
template: z22.string().min(1).max(2048)
|
|
4755
5274
|
}).strict();
|
|
4756
|
-
ApproverSpecSchema =
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
users:
|
|
4761
|
-
|
|
5275
|
+
ApproverSpecSchema = z22.union([
|
|
5276
|
+
z22.literal("creator"),
|
|
5277
|
+
z22.literal("org-admins"),
|
|
5278
|
+
z22.object({
|
|
5279
|
+
users: z22.union([
|
|
5280
|
+
z22.array(z22.string().min(1).max(128)).min(1).max(APPROVER_SPEC_MAX_USERS),
|
|
4762
5281
|
TemplateBindingSchema
|
|
4763
5282
|
])
|
|
4764
5283
|
}).strict(),
|
|
4765
|
-
|
|
4766
|
-
role:
|
|
4767
|
-
|
|
5284
|
+
z22.object({
|
|
5285
|
+
role: z22.union([
|
|
5286
|
+
z22.string().min(1).max(128),
|
|
4768
5287
|
TemplateBindingSchema
|
|
4769
5288
|
])
|
|
4770
5289
|
}).strict(),
|
|
4771
|
-
|
|
4772
|
-
group:
|
|
4773
|
-
|
|
5290
|
+
z22.object({
|
|
5291
|
+
group: z22.union([
|
|
5292
|
+
z22.string().min(1).max(128),
|
|
4774
5293
|
TemplateBindingSchema
|
|
4775
5294
|
])
|
|
4776
5295
|
}).strict(),
|
|
4777
|
-
|
|
4778
|
-
governance:
|
|
4779
|
-
policyId:
|
|
5296
|
+
z22.object({
|
|
5297
|
+
governance: z22.object({
|
|
5298
|
+
policyId: z22.string().min(1).max(128)
|
|
4780
5299
|
}).strict()
|
|
4781
5300
|
}).strict()
|
|
4782
5301
|
]);
|
|
4783
|
-
FourEyesSchema =
|
|
5302
|
+
FourEyesSchema = z22.object({
|
|
4784
5303
|
edit: ApproverSpecSchema,
|
|
4785
5304
|
approve: ApproverSpecSchema
|
|
4786
5305
|
}).strict();
|
|
4787
|
-
EscalationHopSchema =
|
|
5306
|
+
EscalationHopSchema = z22.object({
|
|
4788
5307
|
escalateTo: ApproverSpecSchema,
|
|
4789
|
-
timeoutHours:
|
|
5308
|
+
timeoutHours: z22.number().finite().min(1).max(720)
|
|
4790
5309
|
}).strict();
|
|
4791
|
-
TerminalOutcomeSchema =
|
|
5310
|
+
TerminalOutcomeSchema = z22.enum([
|
|
4792
5311
|
"deny",
|
|
4793
5312
|
"cancel-run",
|
|
4794
5313
|
"fail",
|
|
4795
5314
|
"continue"
|
|
4796
5315
|
]);
|
|
4797
|
-
ApprovalOnTimeoutSchema =
|
|
5316
|
+
ApprovalOnTimeoutSchema = z22.union([
|
|
4798
5317
|
TerminalOutcomeSchema,
|
|
4799
5318
|
EscalationHopSchema,
|
|
4800
|
-
|
|
5319
|
+
z22.array(z22.union([
|
|
4801
5320
|
TerminalOutcomeSchema,
|
|
4802
5321
|
EscalationHopSchema
|
|
4803
5322
|
])).min(1).max(ESCALATION_MAX_HOPS + 1)
|
|
@@ -4850,6 +5369,15 @@ var init_dist2 = __esm({
|
|
|
4850
5369
|
__name3(ofEntry, "ofEntry");
|
|
4851
5370
|
__name(estimateGraph, "estimateGraph");
|
|
4852
5371
|
__name3(estimateGraph, "estimateGraph");
|
|
5372
|
+
isRecord2 = /* @__PURE__ */ __name3((v) => !!v && typeof v === "object" && !Array.isArray(v), "isRecord");
|
|
5373
|
+
__name(singleStepsOf, "singleStepsOf");
|
|
5374
|
+
__name3(singleStepsOf, "singleStepsOf");
|
|
5375
|
+
__name(entriesOf, "entriesOf");
|
|
5376
|
+
__name3(entriesOf, "entriesOf");
|
|
5377
|
+
__name(inheritTargets, "inheritTargets");
|
|
5378
|
+
__name3(inheritTargets, "inheritTargets");
|
|
5379
|
+
__name(needsInheritedWorkspace, "needsInheritedWorkspace");
|
|
5380
|
+
__name3(needsInheritedWorkspace, "needsInheritedWorkspace");
|
|
4853
5381
|
}
|
|
4854
5382
|
});
|
|
4855
5383
|
|
|
@@ -4908,16 +5436,16 @@ function stepNodeOf(s) {
|
|
|
4908
5436
|
});
|
|
4909
5437
|
}
|
|
4910
5438
|
function materializeEntry(entry, steps) {
|
|
4911
|
-
const single = /* @__PURE__ */ __name((
|
|
4912
|
-
if (
|
|
4913
|
-
if (
|
|
4914
|
-
...
|
|
5439
|
+
const single = /* @__PURE__ */ __name((n2) => {
|
|
5440
|
+
if (n2.type === "step" && steps[n2.step.id]) return stepNodeOf(steps[n2.step.id]);
|
|
5441
|
+
if (n2.type === "workflow" && n2.workflowId === WORKFLOW_ARM_SUBRUN_ID && n2.graph) return {
|
|
5442
|
+
...n2,
|
|
4915
5443
|
graph: [
|
|
4916
|
-
|
|
4917
|
-
single(
|
|
5444
|
+
n2.graph[0],
|
|
5445
|
+
single(n2.graph[1])
|
|
4918
5446
|
]
|
|
4919
5447
|
};
|
|
4920
|
-
return
|
|
5448
|
+
return n2;
|
|
4921
5449
|
}, "single");
|
|
4922
5450
|
switch (entry.type) {
|
|
4923
5451
|
case "step":
|
|
@@ -4962,8 +5490,8 @@ function createWorkflow(cfg) {
|
|
|
4962
5490
|
if (v.roles.length > 20 || (v.users?.length ?? 0) > 50) throw new LuaWorkflowBuildError("cap-exceeded", "outputVisibility allows \u2264 20 roles and \u2264 50 users");
|
|
4963
5491
|
}
|
|
4964
5492
|
if (cfg.backfillOnEnable?.maxOccurrences !== void 0) {
|
|
4965
|
-
const
|
|
4966
|
-
if (!Number.isInteger(
|
|
5493
|
+
const n2 = cfg.backfillOnEnable.maxOccurrences;
|
|
5494
|
+
if (!Number.isInteger(n2) || n2 < 1 || n2 > 200) throw new LuaWorkflowBuildError("invalid-envelope", "backfillOnEnable.maxOccurrences must be an integer in 1..200 (backfill-max-occurrences-out-of-range; the org maxBatchItems twin is checked at publish/R56)");
|
|
4967
5495
|
}
|
|
4968
5496
|
const keys = /* @__PURE__ */ new Set();
|
|
4969
5497
|
envRefKeys(cfg.schedule, keys);
|
|
@@ -5154,7 +5682,7 @@ var init_workflow = __esm({
|
|
|
5154
5682
|
getEnvTemplateKeys() {
|
|
5155
5683
|
return this.built.envTemplateKeys;
|
|
5156
5684
|
}
|
|
5157
|
-
/** `.workflow(id, ref)` targets by name — `ManifestWorkflow.workflowRefs
|
|
5685
|
+
/** `.workflow(id, ref)` targets by name — `ManifestWorkflow.workflowRefs`; `workspace:'inherit'` marks the inherit children the compiler defers `workspace-not-declared` for. */
|
|
5158
5686
|
getNestedWorkflowRefs() {
|
|
5159
5687
|
return this.built.nestedRefs;
|
|
5160
5688
|
}
|
|
@@ -5184,6 +5712,7 @@ var init_workflow = __esm({
|
|
|
5184
5712
|
};
|
|
5185
5713
|
if (cfg.concurrencyPolicy !== void 0) envelope.concurrencyPolicy = cfg.concurrencyPolicy;
|
|
5186
5714
|
if (cfg.workspace !== void 0) envelope.workspace = cfg.workspace;
|
|
5715
|
+
if (cfg.connections !== void 0) envelope.connections = cfg.connections;
|
|
5187
5716
|
return withDefaultsFilled(envelope);
|
|
5188
5717
|
}
|
|
5189
5718
|
};
|
|
@@ -5219,7 +5748,6 @@ var init_workflow = __esm({
|
|
|
5219
5748
|
if (this.steps[s.id] && this.steps[s.id] !== s) throw new LuaWorkflowBuildError("duplicate-step-id", `step id "${s.id}" is declared twice`);
|
|
5220
5749
|
const tier = s.tier ?? (s.workspace ? "job" : void 0);
|
|
5221
5750
|
if (s.workspace && s.tier !== void 0 && s.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${s.id}": a step mounting a workspace must be tier:'job'`);
|
|
5222
|
-
if (s.workspace && !this.config.workspace) throw new LuaWorkflowBuildError("workspace-not-declared", `"${s.id}" mounts a workspace but createWorkflow declares none`);
|
|
5223
5751
|
if (s.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${s.id}": jobTools require tier:'job' (job-tools-require-job-tier)`);
|
|
5224
5752
|
assertTimeout({
|
|
5225
5753
|
id: s.id,
|
|
@@ -5460,13 +5988,20 @@ var init_workflow = __esm({
|
|
|
5460
5988
|
}
|
|
5461
5989
|
const tier = opts.tier ?? (opts.workspace ? "job" : void 0);
|
|
5462
5990
|
if (opts.workspace && opts.tier !== void 0 && opts.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${id}": a step mounting a workspace must be tier:'job'`);
|
|
5463
|
-
if (opts.workspace && !this.config.workspace) throw new LuaWorkflowBuildError("workspace-not-declared", `"${id}" mounts a workspace but createWorkflow declares none`);
|
|
5464
5991
|
if (opts.harness !== void 0 && tier !== "job") throw new LuaWorkflowBuildError("harness-requires-job-tier", `"${id}": harness is only legal on a tier:'job' agent step`);
|
|
5465
5992
|
if (opts.toolScope?.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${id}": toolScope.jobTools require tier:'job' (job-tools-require-job-tier)`);
|
|
5466
5993
|
if (opts.maxTurns !== void 0) {
|
|
5467
5994
|
if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id}": maxTurns is only legal on a tier:'job' agent step`);
|
|
5468
5995
|
if (!Number.isInteger(opts.maxTurns) || opts.maxTurns < 1 || opts.maxTurns > 500) throw new LuaWorkflowBuildError("max-turns-invalid", `"${id}": maxTurns must be an integer 1..500`);
|
|
5469
5996
|
}
|
|
5997
|
+
if (opts.maxMessages !== void 0) {
|
|
5998
|
+
if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id}": maxMessages is only legal on a tier:'job' agent step`);
|
|
5999
|
+
if (!Number.isInteger(opts.maxMessages) || opts.maxMessages < 1 || opts.maxMessages > 5e3) throw new LuaWorkflowBuildError("max-turns-invalid", `"${id}": maxMessages must be an integer 1..5000`);
|
|
6000
|
+
}
|
|
6001
|
+
if (opts.maxInputTokens !== void 0) {
|
|
6002
|
+
if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id}": maxInputTokens is only legal on a tier:'job' agent step`);
|
|
6003
|
+
if (!Number.isInteger(opts.maxInputTokens) || opts.maxInputTokens < 1e6 || opts.maxInputTokens > 5e8) throw new LuaWorkflowBuildError("max-turns-invalid", `"${id}": maxInputTokens must be an integer 1000000..500000000`);
|
|
6004
|
+
}
|
|
5470
6005
|
assertTimeout({
|
|
5471
6006
|
id,
|
|
5472
6007
|
timeoutSeconds: opts.timeoutSeconds,
|
|
@@ -5493,7 +6028,9 @@ var init_workflow = __esm({
|
|
|
5493
6028
|
workspace: opts.workspace,
|
|
5494
6029
|
jobResources: opts.jobResources,
|
|
5495
6030
|
harness: opts.harness,
|
|
5496
|
-
maxTurns: opts.maxTurns
|
|
6031
|
+
maxTurns: opts.maxTurns,
|
|
6032
|
+
maxMessages: opts.maxMessages,
|
|
6033
|
+
maxInputTokens: opts.maxInputTokens
|
|
5497
6034
|
});
|
|
5498
6035
|
return this.push({
|
|
5499
6036
|
kind: "declare",
|
|
@@ -5648,7 +6185,11 @@ var init_workflow = __esm({
|
|
|
5648
6185
|
}
|
|
5649
6186
|
assertNoClosure(input, `workflow("${id}").input`);
|
|
5650
6187
|
this.recordEnvRefs(input);
|
|
5651
|
-
this.nestedRefs.push({
|
|
6188
|
+
this.nestedRefs.push(opts?.workspace === "inherit" ? {
|
|
6189
|
+
id,
|
|
6190
|
+
name,
|
|
6191
|
+
workspace: "inherit"
|
|
6192
|
+
} : {
|
|
5652
6193
|
id,
|
|
5653
6194
|
name
|
|
5654
6195
|
});
|
|
@@ -5660,8 +6201,8 @@ var init_workflow = __esm({
|
|
|
5660
6201
|
workspace: opts?.workspace
|
|
5661
6202
|
});
|
|
5662
6203
|
return this.push({
|
|
5663
|
-
kind: "
|
|
5664
|
-
|
|
6204
|
+
kind: "declare",
|
|
6205
|
+
node
|
|
5665
6206
|
});
|
|
5666
6207
|
}
|
|
5667
6208
|
commit() {
|
|
@@ -5671,7 +6212,7 @@ var init_workflow = __esm({
|
|
|
5671
6212
|
const { graph, issues } = resolvePlacements(this.calls);
|
|
5672
6213
|
const fatal = issues[0];
|
|
5673
6214
|
if (fatal) {
|
|
5674
|
-
const hint = fatal.code === "unknown-step-ref" ? "a string StepRef must name an entry declared by agentStep/specialistStep/toolStep/map(\u2026, { id }) somewhere in the chain \u2014 before OR after the reference" : void 0;
|
|
6215
|
+
const hint = fatal.code === "unknown-step-ref" ? "a string StepRef must name an entry declared by agentStep/specialistStep/toolStep/map(\u2026, { id })/workflow(\u2026) somewhere in the chain \u2014 before OR after the reference" : void 0;
|
|
5675
6216
|
throw new LuaWorkflowBuildError(fatal.code, fatal.message, hint);
|
|
5676
6217
|
}
|
|
5677
6218
|
if (graph.length === 0) throw new LuaWorkflowBuildError("empty-graph", `workflow "${this.config.name}" has no entries`);
|
|
@@ -5684,7 +6225,8 @@ var init_workflow = __esm({
|
|
|
5684
6225
|
if (graphHasHitl(graph, this.steps) && this.config.budget?.maxDurationSeconds === void 0) {
|
|
5685
6226
|
this.warnings.push({
|
|
5686
6227
|
code: "hitl-duration-defaulted",
|
|
5687
|
-
|
|
6228
|
+
// LUA-668: names the workflow — two HITL workflows in one project printed two identical lines that read as a duplicate.
|
|
6229
|
+
message: `workflow "${this.config.name}": budget.maxDurationSeconds defaulted to ${WORKFLOW_HITL_MAX_DURATION_SECONDS} s (30 d) because the graph contains an approval / waitForSignal / suspend-capable step \u2014 set it explicitly to silence`
|
|
5688
6230
|
});
|
|
5689
6231
|
}
|
|
5690
6232
|
this.checkScheduleInput();
|
|
@@ -11215,7 +11757,7 @@ function createWorkflowsRuntime(getApi) {
|
|
|
11215
11757
|
}
|
|
11216
11758
|
};
|
|
11217
11759
|
}
|
|
11218
|
-
var WORKFLOW_START_MAX_WAIT_SECONDS, WORKFLOW_START_CLIENT_DEADLINE_SLACK_MS, WorkflowApiError, unwrap, assertBoundAgent, unavailable, WorkflowApi;
|
|
11760
|
+
var WORKFLOW_START_MAX_WAIT_SECONDS, WORKFLOW_START_CLIENT_DEADLINE_SLACK_MS, WorkflowApiError, unwrap, assertBoundAgent, pathId, unavailable, WorkflowApi;
|
|
11219
11761
|
var init_workflow_api_service = __esm({
|
|
11220
11762
|
"src/api/workflow.api.service.ts"() {
|
|
11221
11763
|
"use strict";
|
|
@@ -11252,6 +11794,7 @@ var init_workflow_api_service = __esm({
|
|
|
11252
11794
|
throw new WorkflowApiError("FORBIDDEN", `Workflows.${member}: goals are scoped to the bound agent ${api.agentId}`, 403);
|
|
11253
11795
|
}
|
|
11254
11796
|
}, "assertBoundAgent");
|
|
11797
|
+
pathId = /* @__PURE__ */ __name((id) => encodeURIComponent(id), "pathId");
|
|
11255
11798
|
unavailable = /* @__PURE__ */ __name((member, route) => async () => {
|
|
11256
11799
|
throw new WorkflowApiError("WORKFLOWS_API_UNAVAILABLE", `Workflows.${member} is not available in this runtime yet (${route} lands with a later wave)`, 501);
|
|
11257
11800
|
}, "unavailable");
|
|
@@ -11377,7 +11920,7 @@ var init_workflow_api_service = __esm({
|
|
|
11377
11920
|
/** R5 — one step of a run (`?attempt=n` selects from the attempt history). */
|
|
11378
11921
|
async getRunStep(runId, stepId, options = {}) {
|
|
11379
11922
|
const qs = options.attempt !== void 0 ? `?attempt=${options.attempt}` : "";
|
|
11380
|
-
return this.httpGet(`${this.runs}/${runId}/steps/${stepId}${qs}`, await this.auth());
|
|
11923
|
+
return this.httpGet(`${this.runs}/${runId}/steps/${pathId(stepId)}${qs}`, await this.auth());
|
|
11381
11924
|
}
|
|
11382
11925
|
/** R6 — script-form journal page (404 `NOT_SCRIPT_RUN` for graph runs — IF-16). */
|
|
11383
11926
|
async getRunJournal(runId, options = {}) {
|
|
@@ -11397,7 +11940,7 @@ var init_workflow_api_service = __esm({
|
|
|
11397
11940
|
}
|
|
11398
11941
|
/** R12 — resume a suspended step; the loser of a race gets `{ resumed:false, reason:'already_resumed' }`, never a 4xx. */
|
|
11399
11942
|
async resumeRun(runId, stepId, data) {
|
|
11400
|
-
return this.httpPost(`${this.runs}/${runId}/steps/${stepId}/resume`, data, await this.auth());
|
|
11943
|
+
return this.httpPost(`${this.runs}/${runId}/steps/${pathId(stepId)}/resume`, data, await this.auth());
|
|
11401
11944
|
}
|
|
11402
11945
|
/**
|
|
11403
11946
|
* R36 — re-arm a parked step: a failed row past its retries, a gate-2 park, or a billing hold (the only exit
|
|
@@ -11405,15 +11948,15 @@ var init_workflow_api_service = __esm({
|
|
|
11405
11948
|
* STEP_NOT_PARKED.
|
|
11406
11949
|
*/
|
|
11407
11950
|
async retryStep(runId, stepId, data = {}) {
|
|
11408
|
-
return this.httpPost(`${this.runs}/${runId}/steps/${stepId}/retry`, data, await this.auth());
|
|
11951
|
+
return this.httpPost(`${this.runs}/${runId}/steps/${pathId(stepId)}/retry`, data, await this.auth());
|
|
11409
11952
|
}
|
|
11410
11953
|
/** R13 — resolve an approval (human; `expectedFingerprint` guards against an edited payload — 409 `PAYLOAD_MISMATCH`). */
|
|
11411
11954
|
async resolveApproval(runId, approvalId, data) {
|
|
11412
|
-
return this.httpPost(`${this.runs}/${runId}/approvals/${approvalId}/resolve`, data, await this.auth());
|
|
11955
|
+
return this.httpPost(`${this.runs}/${runId}/approvals/${pathId(approvalId)}/resolve`, data, await this.auth());
|
|
11413
11956
|
}
|
|
11414
11957
|
/** R14 — deliver a named signal (`dedupeKey` ⇒ 200 `duplicate:true` on replay). */
|
|
11415
11958
|
async signalRun(runId, name, data = {}) {
|
|
11416
|
-
return this.httpPost(`${this.runs}/${runId}/signals/${
|
|
11959
|
+
return this.httpPost(`${this.runs}/${runId}/signals/${pathId(name)}`, data, await this.auth());
|
|
11417
11960
|
}
|
|
11418
11961
|
/** R31 — `DELETE …/runs/:runId` (`eraseRun`; human principal) → 202 `{ accepted, purgeId }`; 409 `RUN_NOT_TERMINAL { nextAction:'cancel' }`. */
|
|
11419
11962
|
/** R50 — request an evidence-bundle export (202 `{exportId, status:'pending'}`; 409 `RUN_NOT_TERMINAL` / `EXPORT_IN_PROGRESS`). */
|
|
@@ -11470,6 +12013,23 @@ var init_workflow_api_service = __esm({
|
|
|
11470
12013
|
async closeGoal(goalId, data = {}) {
|
|
11471
12014
|
return this.httpPost(`${this.goals}/${encodeURIComponent(goalId)}/close`, data, await this.auth());
|
|
11472
12015
|
}
|
|
12016
|
+
// ─── Schedules (R4-MF-2 list/get + R28 delete — `/workflows/:agentId/schedules`; LUA-627 stanza) ───
|
|
12017
|
+
/** Schedule tree (09 §9.5 — the write-only R27/R56/R28 family plus the R4-MF-2 read rows). */
|
|
12018
|
+
get schedules() {
|
|
12019
|
+
return `/workflows/${this.agentId}/schedules`;
|
|
12020
|
+
}
|
|
12021
|
+
/** R4-MF-2 — every `Job{kind:'workflow'}` of the agent with the PRO-726 strike fields (`goalId` marks a goal's cadence). */
|
|
12022
|
+
async listSchedules() {
|
|
12023
|
+
return this.httpGet(this.schedules, await this.auth());
|
|
12024
|
+
}
|
|
12025
|
+
/** R4-MF-2 — one schedule row; unknown, cross-agent and non-workflow-kind jobs all 404 `SCHEDULE_NOT_FOUND`. */
|
|
12026
|
+
async getSchedule(jobId) {
|
|
12027
|
+
return this.httpGet(`${this.schedules}/${encodeURIComponent(jobId)}`, await this.auth());
|
|
12028
|
+
}
|
|
12029
|
+
/** R28 — delete a schedule Job (404 `SCHEDULE_NOT_FOUND`). The CLI refuses a goal-owned job BEFORE this call (`goal_schedule`). */
|
|
12030
|
+
async deleteSchedule(jobId) {
|
|
12031
|
+
return this.httpDelete(`${this.schedules}/${encodeURIComponent(jobId)}`, await this.auth());
|
|
12032
|
+
}
|
|
11473
12033
|
// ─── Events (R7 — SSE `watch`, WF-204) ───
|
|
11474
12034
|
/**
|
|
11475
12035
|
* R7 SSE — `GET …/runs/:runId/events` as a frame stream (`id:<seq>` / `event:<type>` /
|
|
@@ -11513,7 +12073,7 @@ var init_workflow_api_service = __esm({
|
|
|
11513
12073
|
if (options.attempt !== void 0) query.append("attempt", String(options.attempt));
|
|
11514
12074
|
if (options.tail !== void 0) query.append("tail", String(options.tail));
|
|
11515
12075
|
const qs = query.toString();
|
|
11516
|
-
return this.httpGet(`${this.runs}/${runId}/steps/${stepId}/job${qs ? `?${qs}` : ""}`, await this.auth());
|
|
12076
|
+
return this.httpGet(`${this.runs}/${runId}/steps/${pathId(stepId)}/job${qs ? `?${qs}` : ""}`, await this.auth());
|
|
11517
12077
|
}
|
|
11518
12078
|
};
|
|
11519
12079
|
}
|