lua-cli 3.32.2 → 3.32.3
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 +82 -8
- package/dist/api-exports.js +765 -304
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +2082 -549
- package/dist/index.js.map +1 -1
- package/dist/workflow-builder.d.ts +11 -7
- package/dist/workflow-builder.js +588 -244
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +126 -4
- package/docs/README.md +2 -2
- package/docs/workflows/approvals.md +24 -6
- package/docs/workflows/goals.md +2 -2
- package/docs/workflows/replay-local.md +9 -3
- package/docs/workflows/schedules.md +1 -1
- package/docs/workflows/script-form.md +4 -4
- package/docs/workflows/testing-offline.md +33 -21
- package/package.json +4 -3
- package/template/examples/workflows/CLAUDE.md +17 -11
- package/template/examples/workflows/adversarial-verify.workflow.script.js +20 -16
- package/template/examples/workflows/outreach.ts +31 -15
- package/template/examples/workflows/refund-approval.ts +26 -12
- package/template/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64,6 +64,261 @@ var init_auth_error = __esm({
|
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
// src/errors/cli.error.ts
|
|
68
|
+
function isAccessDeniedError(error) {
|
|
69
|
+
if (CliError.isCliError(error)) return error.statusCode === 403;
|
|
70
|
+
return error instanceof Error && error.message.startsWith("Access denied (403)");
|
|
71
|
+
}
|
|
72
|
+
function isHandledCliError(error) {
|
|
73
|
+
return error instanceof HandledCliError || typeof error === "object" && error !== null && error.handled === true && typeof error.exitCode === "number";
|
|
74
|
+
}
|
|
75
|
+
function setDebugMode(enabled) {
|
|
76
|
+
debugFlag = enabled;
|
|
77
|
+
}
|
|
78
|
+
function debugEnabled() {
|
|
79
|
+
const v = process.env.LUA_DEBUG;
|
|
80
|
+
return debugFlag || v === "1" || v === "true" || v === "yes";
|
|
81
|
+
}
|
|
82
|
+
function authHint(error) {
|
|
83
|
+
if (error.suppressDefaultRemediation) return void 0;
|
|
84
|
+
if (error.reason === "no_agent_access") {
|
|
85
|
+
return [
|
|
86
|
+
"Your API key is valid, but it does not have access to the agentId in lua.skill.yaml \u2014 the agent belongs",
|
|
87
|
+
"to another account or organization, was deleted or transferred, or the yaml was copied from another project.",
|
|
88
|
+
"Check the configured agent and switch if needed:",
|
|
89
|
+
" lua agents (list agents you have access to)",
|
|
90
|
+
" lua init (re-select the agent for this project)"
|
|
91
|
+
].join("\n");
|
|
92
|
+
}
|
|
93
|
+
return "Re-authenticate or check your API key: lua auth configure \xB7 https://admin.heylua.ai";
|
|
94
|
+
}
|
|
95
|
+
function numericStatus(error) {
|
|
96
|
+
const candidate = error.statusCode ?? error.status;
|
|
97
|
+
return typeof candidate === "number" && Number.isFinite(candidate) ? candidate : void 0;
|
|
98
|
+
}
|
|
99
|
+
function classifyCliError(error) {
|
|
100
|
+
if (CliError.isCliError(error)) {
|
|
101
|
+
return {
|
|
102
|
+
code: error.code,
|
|
103
|
+
exitCode: error.exitCode,
|
|
104
|
+
message: error.message,
|
|
105
|
+
hint: error.hint
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (AuthenticationError.isAuthenticationError(error)) {
|
|
109
|
+
return {
|
|
110
|
+
code: "auth",
|
|
111
|
+
exitCode: CLI_EXIT.AUTH,
|
|
112
|
+
message: error.message,
|
|
113
|
+
hint: authHint(error)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const e = typeof error === "object" && error !== null ? error : {};
|
|
117
|
+
const message = typeof e.message === "string" && e.message.length > 0 ? e.message : error instanceof Error ? error.name : String(error ?? "Unknown error");
|
|
118
|
+
if (e.name === "WorkflowLocalUsageError" || typeof e.code === "string" && e.code.startsWith("commander.")) {
|
|
119
|
+
return {
|
|
120
|
+
code: "usage",
|
|
121
|
+
exitCode: CLI_EXIT.USAGE,
|
|
122
|
+
message
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const status = numericStatus(e);
|
|
126
|
+
if (status !== void 0) {
|
|
127
|
+
if (status === 401) return {
|
|
128
|
+
code: "auth",
|
|
129
|
+
exitCode: CLI_EXIT.AUTH,
|
|
130
|
+
message
|
|
131
|
+
};
|
|
132
|
+
if (status === 403) return {
|
|
133
|
+
code: "forbidden",
|
|
134
|
+
exitCode: CLI_EXIT.FORBIDDEN,
|
|
135
|
+
message
|
|
136
|
+
};
|
|
137
|
+
if (status === 404) return {
|
|
138
|
+
code: "not_found",
|
|
139
|
+
exitCode: CLI_EXIT.NOT_FOUND,
|
|
140
|
+
message
|
|
141
|
+
};
|
|
142
|
+
if (status >= 400 && status < 500) return {
|
|
143
|
+
code: `http_${status}`,
|
|
144
|
+
exitCode: CLI_EXIT.FORBIDDEN,
|
|
145
|
+
message
|
|
146
|
+
};
|
|
147
|
+
if (status >= 500 || status === 0) return {
|
|
148
|
+
code: "unavailable",
|
|
149
|
+
exitCode: CLI_EXIT.UNAVAILABLE,
|
|
150
|
+
message
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const causeCode = e.cause?.code;
|
|
154
|
+
if (typeof e.code === "string" && NETWORK_ERRNO.has(e.code) || typeof causeCode === "string" && NETWORK_ERRNO.has(causeCode) || e.name === "AbortError" || e.name === "TimeoutError" || NETWORK_MESSAGE.test(message)) {
|
|
155
|
+
return {
|
|
156
|
+
code: "unavailable",
|
|
157
|
+
exitCode: CLI_EXIT.UNAVAILABLE,
|
|
158
|
+
message,
|
|
159
|
+
hint: UNAVAILABLE_HINT
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
code: "error",
|
|
164
|
+
exitCode: CLI_EXIT.ERROR,
|
|
165
|
+
message
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function renderCliError(reported, options = {}) {
|
|
169
|
+
const lines = [
|
|
170
|
+
`\u2716 ${reported.code}: ${reported.message}`
|
|
171
|
+
];
|
|
172
|
+
for (const hint of [
|
|
173
|
+
reported.hint,
|
|
174
|
+
options.extraHint
|
|
175
|
+
]) {
|
|
176
|
+
if (!hint) continue;
|
|
177
|
+
hint.split("\n").forEach((line, i) => lines.push(i === 0 ? `\u{1F4A1} ${line}` : ` ${line}`));
|
|
178
|
+
}
|
|
179
|
+
if (options.stack) lines.push("", options.stack);
|
|
180
|
+
return lines;
|
|
181
|
+
}
|
|
182
|
+
function reportCliError(error, options = {}) {
|
|
183
|
+
const reported = classifyCliError(error);
|
|
184
|
+
const stack = debugEnabled() && error instanceof Error ? error.stack : void 0;
|
|
185
|
+
for (const line of renderCliError(reported, {
|
|
186
|
+
extraHint: options.extraHint,
|
|
187
|
+
stack
|
|
188
|
+
})) console.error(line);
|
|
189
|
+
return reported;
|
|
190
|
+
}
|
|
191
|
+
function commanderExitCode(error) {
|
|
192
|
+
const e = error;
|
|
193
|
+
const code = e?.code;
|
|
194
|
+
if (typeof code !== "string" || !code.startsWith("commander.")) return void 0;
|
|
195
|
+
if (code === "commander.helpDisplayed" || code === "commander.version") return CLI_EXIT.OK;
|
|
196
|
+
if (code === "commander.help") return e?.exitCode === 0 ? CLI_EXIT.OK : CLI_EXIT.USAGE;
|
|
197
|
+
return CLI_EXIT.USAGE;
|
|
198
|
+
}
|
|
199
|
+
function reportUnhandledCliError(error) {
|
|
200
|
+
if (isHandledCliError(error)) {
|
|
201
|
+
process.exitCode = error.exitCode;
|
|
202
|
+
return error.exitCode;
|
|
203
|
+
}
|
|
204
|
+
const commander = commanderExitCode(error);
|
|
205
|
+
if (commander !== void 0) {
|
|
206
|
+
process.exitCode = commander;
|
|
207
|
+
return commander;
|
|
208
|
+
}
|
|
209
|
+
const reported = reportCliError(error);
|
|
210
|
+
process.exitCode = reported.exitCode;
|
|
211
|
+
return reported.exitCode;
|
|
212
|
+
}
|
|
213
|
+
var CLI_EXIT, CliError, HandledCliError, debugFlag, NETWORK_ERRNO, NETWORK_MESSAGE, UNAVAILABLE_HINT, CLI_EXIT_CODE_HELP;
|
|
214
|
+
var init_cli_error = __esm({
|
|
215
|
+
"src/errors/cli.error.ts"() {
|
|
216
|
+
"use strict";
|
|
217
|
+
init_auth_error();
|
|
218
|
+
CLI_EXIT = {
|
|
219
|
+
OK: 0,
|
|
220
|
+
ERROR: 1,
|
|
221
|
+
USAGE: 2,
|
|
222
|
+
NOT_FOUND: 3,
|
|
223
|
+
AUTH: 9,
|
|
224
|
+
FORBIDDEN: 10,
|
|
225
|
+
UNAVAILABLE: 11
|
|
226
|
+
};
|
|
227
|
+
CliError = class _CliError extends Error {
|
|
228
|
+
static {
|
|
229
|
+
__name(this, "CliError");
|
|
230
|
+
}
|
|
231
|
+
isCliError = true;
|
|
232
|
+
code;
|
|
233
|
+
exitCode;
|
|
234
|
+
hint;
|
|
235
|
+
statusCode;
|
|
236
|
+
constructor(code, message, options = {}) {
|
|
237
|
+
super(message);
|
|
238
|
+
this.name = "CliError";
|
|
239
|
+
this.code = code;
|
|
240
|
+
this.exitCode = options.exitCode ?? CLI_EXIT.ERROR;
|
|
241
|
+
this.hint = options.hint;
|
|
242
|
+
this.statusCode = options.statusCode;
|
|
243
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, _CliError);
|
|
244
|
+
}
|
|
245
|
+
/** Bad arguments, an unknown action, no project — exit 2. */
|
|
246
|
+
static usage(message, hint) {
|
|
247
|
+
return new _CliError("usage", message, {
|
|
248
|
+
exitCode: CLI_EXIT.USAGE,
|
|
249
|
+
hint
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/** The named thing does not exist — exit 3. */
|
|
253
|
+
static notFound(message, hint) {
|
|
254
|
+
return new _CliError("not_found", message, {
|
|
255
|
+
exitCode: CLI_EXIT.NOT_FOUND,
|
|
256
|
+
hint,
|
|
257
|
+
statusCode: 404
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
/** The credential may not do this — exit 10. */
|
|
261
|
+
static forbidden(message, hint) {
|
|
262
|
+
return new _CliError("forbidden", message, {
|
|
263
|
+
exitCode: CLI_EXIT.FORBIDDEN,
|
|
264
|
+
hint,
|
|
265
|
+
statusCode: 403
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
static isCliError(error) {
|
|
269
|
+
return error instanceof _CliError || typeof error === "object" && error !== null && error.isCliError === true;
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
__name(isAccessDeniedError, "isAccessDeniedError");
|
|
273
|
+
HandledCliError = class extends Error {
|
|
274
|
+
static {
|
|
275
|
+
__name(this, "HandledCliError");
|
|
276
|
+
}
|
|
277
|
+
handled = true;
|
|
278
|
+
exitCode;
|
|
279
|
+
/** The error that was reported. */
|
|
280
|
+
original;
|
|
281
|
+
constructor(message, exitCode, original) {
|
|
282
|
+
super(message);
|
|
283
|
+
this.name = "HandledCliError";
|
|
284
|
+
this.exitCode = exitCode;
|
|
285
|
+
this.original = original;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
__name(isHandledCliError, "isHandledCliError");
|
|
289
|
+
debugFlag = false;
|
|
290
|
+
__name(setDebugMode, "setDebugMode");
|
|
291
|
+
__name(debugEnabled, "debugEnabled");
|
|
292
|
+
NETWORK_ERRNO = /* @__PURE__ */ new Set([
|
|
293
|
+
"ECONNREFUSED",
|
|
294
|
+
"ECONNRESET",
|
|
295
|
+
"ENOTFOUND",
|
|
296
|
+
"ETIMEDOUT",
|
|
297
|
+
"EAI_AGAIN",
|
|
298
|
+
"EPIPE",
|
|
299
|
+
"EHOSTUNREACH",
|
|
300
|
+
"ENETUNREACH",
|
|
301
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
302
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
303
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
304
|
+
"UND_ERR_SOCKET"
|
|
305
|
+
]);
|
|
306
|
+
NETWORK_MESSAGE = /fetch failed|socket hang up|network request failed|request timeout|ECONNREFUSED|ENOTFOUND/i;
|
|
307
|
+
UNAVAILABLE_HINT = "The Lua API could not be reached \u2014 check your network and https://status.heylua.ai, then retry.";
|
|
308
|
+
__name(authHint, "authHint");
|
|
309
|
+
__name(numericStatus, "numericStatus");
|
|
310
|
+
__name(classifyCliError, "classifyCliError");
|
|
311
|
+
__name(renderCliError, "renderCliError");
|
|
312
|
+
__name(reportCliError, "reportCliError");
|
|
313
|
+
__name(commanderExitCode, "commanderExitCode");
|
|
314
|
+
__name(reportUnhandledCliError, "reportUnhandledCliError");
|
|
315
|
+
CLI_EXIT_CODE_HELP = `Exit codes: 0 ok \xB7 1 error \xB7 2 usage \xB7 3 not found \xB7 9 auth (401) \xB7 10 forbidden (403 / other 4xx) \xB7
|
|
316
|
+
11 unavailable (5xx / network). lua workflows adds 4 run failed \xB7 5 run cancelled \xB7 6 run gated \xB7
|
|
317
|
+
7 --timeout reached \xB7 8 run parked waiting for a human.
|
|
318
|
+
Errors: one line \u2014 \u2716 <code>: <message> \u2014 plus a \u{1F4A1} hint; LUA_DEBUG=1 prints the stack.`;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
67
322
|
// src/utils/semver.ts
|
|
68
323
|
function parseVersion(version) {
|
|
69
324
|
const [versionPart, preReleasePart] = version.split("-");
|
|
@@ -998,6 +1253,48 @@ function scheduledTimeKey(scheduledTime) {
|
|
|
998
1253
|
function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
|
|
999
1254
|
return scheduledWorkflowRunId(jobId, scheduledTime);
|
|
1000
1255
|
}
|
|
1256
|
+
function workflowRetryMaxAttemptsMessage(got) {
|
|
1257
|
+
const tail = got === void 0 ? "" : ` (got ${JSON.stringify(got)})`;
|
|
1258
|
+
return `\`retry.maxAttempts\` must be an integer ${WORKFLOW_RETRY_MIN_ATTEMPTS}..${WORKFLOW_RETRY_MAX_ATTEMPTS}${tail}`;
|
|
1259
|
+
}
|
|
1260
|
+
function isWithinWorkflowRetryAttempts(value3) {
|
|
1261
|
+
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_RETRY_MIN_ATTEMPTS && value3 <= WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
1262
|
+
}
|
|
1263
|
+
function workflowRetryUnknownMembersMessage(keys) {
|
|
1264
|
+
const named = keys.map((k) => {
|
|
1265
|
+
const engine = WORKFLOW_RETRY_ENGINE_KEYS.includes(k);
|
|
1266
|
+
return `\`${k}\`${engine ? " (engine-owned \u2014 stamped by resetAttempts, never authored)" : ""}`;
|
|
1267
|
+
});
|
|
1268
|
+
return `\`retry\` has no member ${named.join(", ")}; members: ${WORKFLOW_RETRY_POLICY_KEYS.join(", ")}`;
|
|
1269
|
+
}
|
|
1270
|
+
function unknownWorkflowRetryMembers(retry) {
|
|
1271
|
+
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return [];
|
|
1272
|
+
return Object.keys(retry).filter((k) => !WORKFLOW_RETRY_POLICY_KEYS.includes(k));
|
|
1273
|
+
}
|
|
1274
|
+
function authoredRetryPolicy(retry) {
|
|
1275
|
+
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return void 0;
|
|
1276
|
+
const src = retry;
|
|
1277
|
+
const out = {};
|
|
1278
|
+
for (const k of WORKFLOW_RETRY_POLICY_KEYS) if (src[k] !== void 0) out[k] = src[k];
|
|
1279
|
+
return Object.keys(out).length ? out : void 0;
|
|
1280
|
+
}
|
|
1281
|
+
function retryBudgetBaseAttempt(row2) {
|
|
1282
|
+
const base = row2.retry?.budgetBaseAttempt;
|
|
1283
|
+
return typeof base === "number" && Number.isSafeInteger(base) && base > 0 ? base : 0;
|
|
1284
|
+
}
|
|
1285
|
+
function retryBudgetAttempt(row2) {
|
|
1286
|
+
return Math.max(0, row2.attempt - retryBudgetBaseAttempt(row2));
|
|
1287
|
+
}
|
|
1288
|
+
function retryBudgetMaxAttempts(row2) {
|
|
1289
|
+
const max = row2.retry?.maxAttempts;
|
|
1290
|
+
return typeof max === "number" && Number.isFinite(max) && max >= 1 ? max : 1;
|
|
1291
|
+
}
|
|
1292
|
+
function retryBudgetRemaining(row2) {
|
|
1293
|
+
return retryBudgetAttempt(row2) < retryBudgetMaxAttempts(row2);
|
|
1294
|
+
}
|
|
1295
|
+
function retriesRemaining(row2) {
|
|
1296
|
+
return Math.max(0, retryBudgetMaxAttempts(row2) - retryBudgetAttempt(row2));
|
|
1297
|
+
}
|
|
1001
1298
|
function isWithinWorkflowJobRange(member, value3) {
|
|
1002
1299
|
const { min, max } = WORKFLOW_JOB_RANGES[member];
|
|
1003
1300
|
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= min && value3 <= max;
|
|
@@ -1185,7 +1482,66 @@ ${PREAMBLE}
|
|
|
1185
1482
|
|
|
1186
1483
|
${items.join("\n\n")}`;
|
|
1187
1484
|
}
|
|
1188
|
-
|
|
1485
|
+
function workflowApprovalDecisionOf(resumeData) {
|
|
1486
|
+
if (resumeData.timedOut === true) return "timed_out";
|
|
1487
|
+
return resumeData.approved === true ? "approved" : "denied";
|
|
1488
|
+
}
|
|
1489
|
+
function workflowApprovalOutput(resumeData) {
|
|
1490
|
+
const decision = typeof resumeData.decision === "string" ? resumeData.decision : workflowApprovalDecisionOf(resumeData);
|
|
1491
|
+
const note = typeof resumeData.note === "string" && resumeData.note.trim() !== "" ? resumeData.note : void 0;
|
|
1492
|
+
const text = typeof resumeData.text === "string" ? resumeData.text : note ?? decision;
|
|
1493
|
+
return {
|
|
1494
|
+
...resumeData,
|
|
1495
|
+
decision,
|
|
1496
|
+
text
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function isWorkflowApprovalOutput(value3) {
|
|
1500
|
+
if (typeof value3 !== "object" || value3 === null || Array.isArray(value3)) return false;
|
|
1501
|
+
const v = value3;
|
|
1502
|
+
return typeof v.approved === "boolean" && WORKFLOW_APPROVAL_OUTPUT_DECISIONS.includes(v.decision) && typeof v.text === "string";
|
|
1503
|
+
}
|
|
1504
|
+
function extractSingleJsonValue(text) {
|
|
1505
|
+
const trimmed = (text ?? "").trim();
|
|
1506
|
+
if (!trimmed) return {
|
|
1507
|
+
reason: "reply is empty"
|
|
1508
|
+
};
|
|
1509
|
+
const fenced = [
|
|
1510
|
+
...trimmed.matchAll(JSON_FENCE_RE)
|
|
1511
|
+
];
|
|
1512
|
+
if (fenced.length > 1) return {
|
|
1513
|
+
reason: "reply carries more than one fenced block"
|
|
1514
|
+
};
|
|
1515
|
+
const candidate = fenced.length === 1 ? fenced[0][1].trim() : trimmed;
|
|
1516
|
+
try {
|
|
1517
|
+
return {
|
|
1518
|
+
value: JSON.parse(candidate)
|
|
1519
|
+
};
|
|
1520
|
+
} catch {
|
|
1521
|
+
if (fenced.length === 1) return {
|
|
1522
|
+
reason: "fenced block is not valid JSON"
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
const opens = [
|
|
1526
|
+
trimmed.indexOf("{"),
|
|
1527
|
+
trimmed.indexOf("[")
|
|
1528
|
+
].filter((i) => i !== -1);
|
|
1529
|
+
const start = opens.length ? Math.min(...opens) : -1;
|
|
1530
|
+
const end = Math.max(trimmed.lastIndexOf("}"), trimmed.lastIndexOf("]"));
|
|
1531
|
+
if (start === -1 || end <= start) return {
|
|
1532
|
+
reason: "reply is not JSON"
|
|
1533
|
+
};
|
|
1534
|
+
try {
|
|
1535
|
+
return {
|
|
1536
|
+
value: JSON.parse(trimmed.slice(start, end + 1))
|
|
1537
|
+
};
|
|
1538
|
+
} catch {
|
|
1539
|
+
return {
|
|
1540
|
+
reason: "reply does not contain a single JSON value"
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
var __defProp2, __name2, 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, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, 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_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, WORKFLOW_RETRY_BACKOFFS, WORKFLOW_RETRY_MIN_ATTEMPTS, WORKFLOW_RETRY_POLICY_KEYS, WORKFLOW_RETRY_MAX_ATTEMPTS, WORKFLOW_RETRY_ENGINE_KEYS, WORKFLOW_JOB_RESOURCES, WORKFLOW_SIDE_EFFECTS, WORKFLOW_JOB_RANGES, WORKFLOW_JOB_RANGE_MEMBERS, WORKFLOW_SINGLE_STEP_TYPES, WORKFLOW_HITL_ENTRY_TYPES, WORKFLOW_ARM_ENTRY_TYPES, WORKFLOW_HITL_ARM_CONTAINERS, WORKFLOW_GRAPH_ENTRY_STEP_KINDS, WORKFLOW_ARM_ENTRY_STEP_KINDS, WORKFLOW_BUDGET_MAX_DURATION_SECONDS, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, ERROR_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_SECRET_KEY_RE, WORKFLOW_RESERVED_SECRET_KEYS, SCRUB_INPUT_MAX_CHARS, SCRUB_CUT_BACKOFF_CHARS, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE, WORKFLOW_APPROVAL_OUTPUT_DECISIONS, WORKFLOW_APPROVAL_OUTPUT_SCHEMA, JSON_FENCE_RE;
|
|
1189
1545
|
var init_dist = __esm({
|
|
1190
1546
|
"../shared-types/dist/index.mjs"() {
|
|
1191
1547
|
"use strict";
|
|
@@ -2306,6 +2662,37 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2306
2662
|
"fixed",
|
|
2307
2663
|
"exponential"
|
|
2308
2664
|
];
|
|
2665
|
+
WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
|
|
2666
|
+
WORKFLOW_RETRY_POLICY_KEYS = [
|
|
2667
|
+
"maxAttempts",
|
|
2668
|
+
"backoffSeconds",
|
|
2669
|
+
"backoff",
|
|
2670
|
+
"maxBackoffSeconds"
|
|
2671
|
+
];
|
|
2672
|
+
WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
|
|
2673
|
+
__name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2674
|
+
__name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2675
|
+
__name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2676
|
+
__name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2677
|
+
WORKFLOW_RETRY_ENGINE_KEYS = [
|
|
2678
|
+
"budgetBaseAttempt"
|
|
2679
|
+
];
|
|
2680
|
+
__name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2681
|
+
__name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2682
|
+
__name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2683
|
+
__name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2684
|
+
__name(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2685
|
+
__name2(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2686
|
+
__name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2687
|
+
__name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2688
|
+
__name(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2689
|
+
__name2(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2690
|
+
__name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2691
|
+
__name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2692
|
+
__name(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2693
|
+
__name2(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2694
|
+
__name(retriesRemaining, "retriesRemaining");
|
|
2695
|
+
__name2(retriesRemaining, "retriesRemaining");
|
|
2309
2696
|
WORKFLOW_JOB_RESOURCES = [
|
|
2310
2697
|
"small",
|
|
2311
2698
|
"medium",
|
|
@@ -2578,6 +2965,8 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2578
2965
|
"workflow.goal.resumed",
|
|
2579
2966
|
"workflow.goal.done",
|
|
2580
2967
|
"workflow.goal.closed",
|
|
2968
|
+
// LUA-760: an ended goal's cadence Job retired (deleted) — inline on done / closed, by R21 / R28, or by sweep #30
|
|
2969
|
+
"workflow.goal.job_retired",
|
|
2581
2970
|
// --- org policy (02 §2.10 / 09 R23) ---
|
|
2582
2971
|
"workflow.policy.retention_changed",
|
|
2583
2972
|
"workflow.policy.pacing_changed",
|
|
@@ -2627,6 +3016,79 @@ listed here; never invent a target.`;
|
|
|
2627
3016
|
__name2(reachingIt, "reachingIt");
|
|
2628
3017
|
__name(renderTargetsBlock, "renderTargetsBlock");
|
|
2629
3018
|
__name2(renderTargetsBlock, "renderTargetsBlock");
|
|
3019
|
+
WORKFLOW_APPROVAL_OUTPUT_DECISIONS = [
|
|
3020
|
+
"approved",
|
|
3021
|
+
"denied",
|
|
3022
|
+
"timed_out"
|
|
3023
|
+
];
|
|
3024
|
+
WORKFLOW_APPROVAL_OUTPUT_SCHEMA = {
|
|
3025
|
+
type: "object",
|
|
3026
|
+
properties: {
|
|
3027
|
+
approved: {
|
|
3028
|
+
type: "boolean"
|
|
3029
|
+
},
|
|
3030
|
+
decision: {
|
|
3031
|
+
type: "string",
|
|
3032
|
+
enum: [
|
|
3033
|
+
...WORKFLOW_APPROVAL_OUTPUT_DECISIONS
|
|
3034
|
+
]
|
|
3035
|
+
},
|
|
3036
|
+
/** the approver's note when given, else the decision word — what `${stepResults.<id>.text}` reads */
|
|
3037
|
+
text: {
|
|
3038
|
+
type: "string"
|
|
3039
|
+
},
|
|
3040
|
+
note: {
|
|
3041
|
+
type: "string"
|
|
3042
|
+
},
|
|
3043
|
+
editedPayload: {},
|
|
3044
|
+
editRevision: {
|
|
3045
|
+
type: "integer"
|
|
3046
|
+
},
|
|
3047
|
+
decidedBy: {
|
|
3048
|
+
type: "object",
|
|
3049
|
+
properties: {
|
|
3050
|
+
id: {
|
|
3051
|
+
type: "string"
|
|
3052
|
+
},
|
|
3053
|
+
kind: {
|
|
3054
|
+
type: "string"
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
},
|
|
3058
|
+
timedOut: {
|
|
3059
|
+
type: "boolean"
|
|
3060
|
+
},
|
|
3061
|
+
escalations: {
|
|
3062
|
+
type: "integer"
|
|
3063
|
+
},
|
|
3064
|
+
evidence: {
|
|
3065
|
+
type: "array",
|
|
3066
|
+
items: {
|
|
3067
|
+
type: "string"
|
|
3068
|
+
}
|
|
3069
|
+
},
|
|
3070
|
+
items: {
|
|
3071
|
+
type: "array",
|
|
3072
|
+
items: {
|
|
3073
|
+
type: "object"
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
},
|
|
3077
|
+
required: [
|
|
3078
|
+
"approved",
|
|
3079
|
+
"decision",
|
|
3080
|
+
"text"
|
|
3081
|
+
]
|
|
3082
|
+
};
|
|
3083
|
+
__name(workflowApprovalDecisionOf, "workflowApprovalDecisionOf");
|
|
3084
|
+
__name2(workflowApprovalDecisionOf, "workflowApprovalDecisionOf");
|
|
3085
|
+
__name(workflowApprovalOutput, "workflowApprovalOutput");
|
|
3086
|
+
__name2(workflowApprovalOutput, "workflowApprovalOutput");
|
|
3087
|
+
__name(isWorkflowApprovalOutput, "isWorkflowApprovalOutput");
|
|
3088
|
+
__name2(isWorkflowApprovalOutput, "isWorkflowApprovalOutput");
|
|
3089
|
+
JSON_FENCE_RE = /```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n?```/g;
|
|
3090
|
+
__name(extractSingleJsonValue, "extractSingleJsonValue");
|
|
3091
|
+
__name2(extractSingleJsonValue, "extractSingleJsonValue");
|
|
2630
3092
|
}
|
|
2631
3093
|
});
|
|
2632
3094
|
|
|
@@ -3133,6 +3595,208 @@ import { createHash as createHash2 } from "crypto";
|
|
|
3133
3595
|
import { z as z6 } from "zod";
|
|
3134
3596
|
import { z as z22 } from "zod";
|
|
3135
3597
|
import { createHash as createHash22 } from "crypto";
|
|
3598
|
+
function isMapConfigObject(v) {
|
|
3599
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3600
|
+
}
|
|
3601
|
+
function parseMapConfig(raw, stepId) {
|
|
3602
|
+
if (isMapConfigObject(raw)) return raw;
|
|
3603
|
+
if (typeof raw !== "string") {
|
|
3604
|
+
throw new Error(`Stored mapping step "${stepId}" has a mapConfig that is neither a JSON string nor an object.`);
|
|
3605
|
+
}
|
|
3606
|
+
try {
|
|
3607
|
+
return JSON.parse(raw);
|
|
3608
|
+
} catch (e) {
|
|
3609
|
+
throw new Error(`Stored mapping step "${stepId}" has invalid JSON mapConfig: ${e.message}`);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
function mapConfigWire(raw) {
|
|
3613
|
+
if (typeof raw === "string") return raw;
|
|
3614
|
+
if (isMapConfigObject(raw)) return canonicalJson(raw);
|
|
3615
|
+
return void 0;
|
|
3616
|
+
}
|
|
3617
|
+
function describeBadPlaceholder(template22, idx, rawExpr) {
|
|
3618
|
+
return `Template placeholder #${idx} (\${${rawExpr}}) in '${template22}'`;
|
|
3619
|
+
}
|
|
3620
|
+
function parseTemplatePlaceholder(rawExpr) {
|
|
3621
|
+
const dot = rawExpr.indexOf(".");
|
|
3622
|
+
return {
|
|
3623
|
+
scope: dot === -1 ? rawExpr : rawExpr.slice(0, dot),
|
|
3624
|
+
rest: dot === -1 ? "" : rawExpr.slice(dot + 1)
|
|
3625
|
+
};
|
|
3626
|
+
}
|
|
3627
|
+
function traverseMappingPath(root, path25, errorLabel2) {
|
|
3628
|
+
if (path25 === "" || path25 === ".") return root;
|
|
3629
|
+
const parts = path25.split(".");
|
|
3630
|
+
let value22 = root;
|
|
3631
|
+
for (const part of parts) {
|
|
3632
|
+
if (typeof value22 === "object" && value22 !== null) value22 = value22[part];
|
|
3633
|
+
else throw new WorkflowTemplateError(`Invalid path ${path25} in ${errorLabel2}`, path25);
|
|
3634
|
+
}
|
|
3635
|
+
return value22;
|
|
3636
|
+
}
|
|
3637
|
+
function stringifyTemplateValue(v, template22, idx, rawExpr) {
|
|
3638
|
+
if (v === null || v === void 0) return "";
|
|
3639
|
+
if (typeof v === "object") {
|
|
3640
|
+
try {
|
|
3641
|
+
return JSON.stringify(v);
|
|
3642
|
+
} catch (err) {
|
|
3643
|
+
throw new WorkflowTemplateError(`${describeBadPlaceholder(template22, idx, rawExpr)} resolved to a value that could not be JSON-stringified (${err.message}).`, rawExpr);
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
return String(v);
|
|
3647
|
+
}
|
|
3648
|
+
function escapeFence(content) {
|
|
3649
|
+
return content.replace(/<\/lua-data/g, "<\\/lua-data");
|
|
3650
|
+
}
|
|
3651
|
+
function fenceBlock(name, source, content) {
|
|
3652
|
+
return `<lua-data name="${name}" source="${source}" untrusted="true">${escapeFence(content)}</lua-data>`;
|
|
3653
|
+
}
|
|
3654
|
+
function renderTemplate(template22, ctx, opts) {
|
|
3655
|
+
let idx = 0;
|
|
3656
|
+
return template22.replace(TEMPLATE_PLACEHOLDER, (_match, rawExpr) => {
|
|
3657
|
+
idx += 1;
|
|
3658
|
+
const { scope, rest } = parseTemplatePlaceholder(rawExpr);
|
|
3659
|
+
const label = describeBadPlaceholder(template22, idx, rawExpr);
|
|
3660
|
+
let rendered;
|
|
3661
|
+
let source;
|
|
3662
|
+
switch (scope) {
|
|
3663
|
+
case "initData":
|
|
3664
|
+
rendered = stringifyTemplateValue(traverseMappingPath(ctx.initData, rest, label), template22, idx, rawExpr);
|
|
3665
|
+
source = "initData";
|
|
3666
|
+
break;
|
|
3667
|
+
case "state":
|
|
3668
|
+
rendered = stringifyTemplateValue(traverseMappingPath(ctx.state, rest, label), template22, idx, rawExpr);
|
|
3669
|
+
source = "state";
|
|
3670
|
+
break;
|
|
3671
|
+
case "requestContext":
|
|
3672
|
+
rendered = stringifyTemplateValue(traverseMappingPath(ctx.requestContext, rest, label), template22, idx, rawExpr);
|
|
3673
|
+
source = "requestContext";
|
|
3674
|
+
break;
|
|
3675
|
+
case "stepResults": {
|
|
3676
|
+
const innerDot = rest.indexOf(".");
|
|
3677
|
+
const stepId = innerDot === -1 ? rest : rest.slice(0, innerDot);
|
|
3678
|
+
const subPath = innerDot === -1 ? "" : rest.slice(innerDot + 1);
|
|
3679
|
+
if (!stepId) throw new WorkflowTemplateError(`${label} must name a step: \${stepResults.<stepId>.<path>}.`, rawExpr);
|
|
3680
|
+
if (!(stepId in ctx.stepResults) || ctx.stepResults[stepId] == null) {
|
|
3681
|
+
throw new WorkflowTemplateError(`${label} references stepResults.${stepId} but step "${stepId}" has no resolvable output (not an ancestor, not run, failed, or produced no output).`, rawExpr);
|
|
3682
|
+
}
|
|
3683
|
+
rendered = stringifyTemplateValue(traverseMappingPath(ctx.stepResults[stepId], subPath, label), template22, idx, rawExpr);
|
|
3684
|
+
source = `step:${stepId}`;
|
|
3685
|
+
break;
|
|
3686
|
+
}
|
|
3687
|
+
default:
|
|
3688
|
+
throw new WorkflowTemplateError(`${label} references unknown namespace "${scope}". Use one of: ${TEMPLATE_NAMESPACES.join(", ")}.`, rawExpr);
|
|
3689
|
+
}
|
|
3690
|
+
return opts.fenced ? fenceBlock(rawExpr, source, rendered) : rendered;
|
|
3691
|
+
});
|
|
3692
|
+
}
|
|
3693
|
+
function isMapDescriptor(v) {
|
|
3694
|
+
if (v === null || typeof v !== "object" || Array.isArray(v)) return false;
|
|
3695
|
+
const d = v;
|
|
3696
|
+
const keys = Object.keys(d);
|
|
3697
|
+
const only = /* @__PURE__ */ __name3((...allowed) => keys.every((k) => allowed.includes(k)), "only");
|
|
3698
|
+
if ("value" in d) return keys.length === 1;
|
|
3699
|
+
if ("template" in d) return keys.length === 1 && typeof d.template === "string";
|
|
3700
|
+
if ("requestContextPath" in d) return keys.length === 1 && typeof d.requestContextPath === "string";
|
|
3701
|
+
if ("knowledge" in d) return keys.length === 1 && typeof d.knowledge === "object" && d.knowledge !== null;
|
|
3702
|
+
if ("initData" in d) return d.initData === true && typeof d.path === "string" && only("initData", "path");
|
|
3703
|
+
if ("step" in d) {
|
|
3704
|
+
const stepOk = typeof d.step === "string" || Array.isArray(d.step) && d.step.every((x) => typeof x === "string");
|
|
3705
|
+
return stepOk && typeof d.path === "string" && only("step", "path", "rows");
|
|
3706
|
+
}
|
|
3707
|
+
return false;
|
|
3708
|
+
}
|
|
3709
|
+
function malformedMapMembers(cfg) {
|
|
3710
|
+
if (!cfg || typeof cfg !== "object" || Array.isArray(cfg)) return [];
|
|
3711
|
+
const out = [];
|
|
3712
|
+
for (const [member, v] of Object.entries(cfg)) {
|
|
3713
|
+
if (!v || typeof v !== "object" || Array.isArray(v) || isMapDescriptor(v)) continue;
|
|
3714
|
+
const keys = Object.keys(v).filter((k) => MAP_DESCRIPTOR_KEYS.includes(k));
|
|
3715
|
+
if (keys.length > 0) out.push({
|
|
3716
|
+
member,
|
|
3717
|
+
keys
|
|
3718
|
+
});
|
|
3719
|
+
}
|
|
3720
|
+
return out;
|
|
3721
|
+
}
|
|
3722
|
+
function mapMemberMalformedMessage(id, m) {
|
|
3723
|
+
const keys = m.keys.map((k) => `\`${k}\``).join(", ");
|
|
3724
|
+
return `"${id}".${m.member} carries descriptor key${m.keys.length === 1 ? "" : "s"} ${keys} but is not an exact binding form ({initData:true, path} | {step, path[, rows]} | {value} | {template} | {requestContextPath} | {knowledge}) \u2014 it is passed to the step verbatim as a literal; fix the descriptor, or wrap it in {value: \u2026} if the literal is intended`;
|
|
3725
|
+
}
|
|
3726
|
+
function resolveDescriptor(key, m, ctx) {
|
|
3727
|
+
if (!isMapDescriptor(m)) return {
|
|
3728
|
+
value: m
|
|
3729
|
+
};
|
|
3730
|
+
try {
|
|
3731
|
+
if ("value" in m) return {
|
|
3732
|
+
value: m.value
|
|
3733
|
+
};
|
|
3734
|
+
if ("template" in m && typeof m.template === "string") {
|
|
3735
|
+
return {
|
|
3736
|
+
value: renderTemplate(m.template, ctx, {
|
|
3737
|
+
fenced: false
|
|
3738
|
+
})
|
|
3739
|
+
};
|
|
3740
|
+
}
|
|
3741
|
+
if ("knowledge" in m || "rows" in m && m.rows !== void 0) {
|
|
3742
|
+
return {
|
|
3743
|
+
error: "binding_unresolved",
|
|
3744
|
+
key
|
|
3745
|
+
};
|
|
3746
|
+
}
|
|
3747
|
+
if ("requestContextPath" in m) {
|
|
3748
|
+
const label = `requestContext path for key "${key}"`;
|
|
3749
|
+
return {
|
|
3750
|
+
value: traverseMappingPath(ctx.requestContext, m.requestContextPath, label)
|
|
3751
|
+
};
|
|
3752
|
+
}
|
|
3753
|
+
if ("path" in m) {
|
|
3754
|
+
const source = "initData" in m && m.initData ? "initData" : "step";
|
|
3755
|
+
if (source === "initData") {
|
|
3756
|
+
return {
|
|
3757
|
+
value: traverseMappingPath(ctx.initData, m.path, `initData for key "${key}"`)
|
|
3758
|
+
};
|
|
3759
|
+
}
|
|
3760
|
+
const stepRef = m.step;
|
|
3761
|
+
const candidates = Array.isArray(stepRef) ? stepRef : [
|
|
3762
|
+
stepRef
|
|
3763
|
+
];
|
|
3764
|
+
const stepId = candidates.find((s) => ctx.stepResults[s] !== void 0 && ctx.stepResults[s] !== null);
|
|
3765
|
+
if (stepId === void 0) return {
|
|
3766
|
+
error: "binding_unresolved",
|
|
3767
|
+
key
|
|
3768
|
+
};
|
|
3769
|
+
return {
|
|
3770
|
+
value: traverseMappingPath(ctx.stepResults[stepId], m.path, `step ${candidates.join("|")} for key "${key}"`)
|
|
3771
|
+
};
|
|
3772
|
+
}
|
|
3773
|
+
return {
|
|
3774
|
+
error: "binding_unresolved",
|
|
3775
|
+
key
|
|
3776
|
+
};
|
|
3777
|
+
} catch (err) {
|
|
3778
|
+
if (err instanceof WorkflowTemplateError) return {
|
|
3779
|
+
error: "binding_unresolved",
|
|
3780
|
+
key
|
|
3781
|
+
};
|
|
3782
|
+
throw err;
|
|
3783
|
+
}
|
|
3784
|
+
}
|
|
3785
|
+
function resolveMapping(cfg, ctx) {
|
|
3786
|
+
const keys = Object.keys(cfg);
|
|
3787
|
+
if (keys.length === 1 && keys[0] === "") {
|
|
3788
|
+
return resolveDescriptor("", cfg[""], ctx);
|
|
3789
|
+
}
|
|
3790
|
+
const result = {};
|
|
3791
|
+
for (const key of keys) {
|
|
3792
|
+
const resolved = resolveDescriptor(key, cfg[key], ctx);
|
|
3793
|
+
if ("error" in resolved) return resolved;
|
|
3794
|
+
result[key] = resolved.value;
|
|
3795
|
+
}
|
|
3796
|
+
return {
|
|
3797
|
+
value: result
|
|
3798
|
+
};
|
|
3799
|
+
}
|
|
3136
3800
|
function workspaceTemplatePath(template22) {
|
|
3137
3801
|
const key = template22.trim();
|
|
3138
3802
|
const expr = WORKSPACE_TEMPLATE_EXPR_RE.exec(key);
|
|
@@ -3293,12 +3957,11 @@ function mapConfigStepRefs(raw) {
|
|
|
3293
3957
|
if (!cfg) return [];
|
|
3294
3958
|
const ids = [];
|
|
3295
3959
|
for (const d of Object.values(cfg)) {
|
|
3296
|
-
if (!d
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
desc.step
|
|
3960
|
+
if (!isMapDescriptor(d)) continue;
|
|
3961
|
+
if ("step" in d) ids.push(...Array.isArray(d.step) ? d.step : [
|
|
3962
|
+
d.step
|
|
3300
3963
|
]);
|
|
3301
|
-
if (
|
|
3964
|
+
if ("template" in d) ids.push(...templateStepRefs(d.template));
|
|
3302
3965
|
}
|
|
3303
3966
|
return ids;
|
|
3304
3967
|
}
|
|
@@ -3423,6 +4086,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3423
4086
|
const r = node.retry;
|
|
3424
4087
|
if (!r) return;
|
|
3425
4088
|
const id = singleId(node);
|
|
4089
|
+
const unknown = unknownWorkflowRetryMembers(r);
|
|
4090
|
+
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path25}.retry`, id);
|
|
4091
|
+
if (r.maxAttempts !== void 0 && !isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
4092
|
+
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
4093
|
+
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path25}.retry.maxAttempts`, id);
|
|
4094
|
+
}
|
|
3426
4095
|
const backoffs = retryBackoffs();
|
|
3427
4096
|
if (r.backoff !== void 0 && !backoffs.includes(r.backoff)) {
|
|
3428
4097
|
const list = backoffs.map((b) => `'${b}'`).join(" | ");
|
|
@@ -3565,6 +4234,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3565
4234
|
const schema = node.type === "step" ? node.step.outputSchema : node.type === "agent" ? node.outputSchema : void 0;
|
|
3566
4235
|
if (schema !== void 0) outputSchemas.set(singleId(node), schema);
|
|
3567
4236
|
}, "recordOutputSchema");
|
|
4237
|
+
const checkMapMembers = /* @__PURE__ */ __name3((cfg, basePath, id) => {
|
|
4238
|
+
for (const m of malformedMapMembers(cfg)) {
|
|
4239
|
+
warn(MAP_MEMBER_MALFORMED_CODE, mapMemberMalformedMessage(id, m), `${basePath}.${m.member}`, id);
|
|
4240
|
+
}
|
|
4241
|
+
}, "checkMapMembers");
|
|
4242
|
+
const checkInputShape = /* @__PURE__ */ __name3((node, path25) => {
|
|
4243
|
+
if (node.type !== "tool" && node.type !== "workflow") return;
|
|
4244
|
+
const input = node.input;
|
|
4245
|
+
if (input === void 0) return;
|
|
4246
|
+
if (input !== null && typeof input === "object" && !Array.isArray(input)) {
|
|
4247
|
+
checkMapMembers(input, `${path25}.input`, node.id);
|
|
4248
|
+
return;
|
|
4249
|
+
}
|
|
4250
|
+
err("invalid-envelope", `\`input\` must be an object map \u2014 each member a binding descriptor ({initData:true, path} | {step, path} | {value} | {template} | {requestContextPath}) or a JSON literal (got ${JSON.stringify(input)})`, `${path25}.input`, node.id);
|
|
4251
|
+
}, "checkInputShape");
|
|
3568
4252
|
const checkSingle = /* @__PURE__ */ __name3((node, path25, depth) => {
|
|
3569
4253
|
recordOutputSchema(node);
|
|
3570
4254
|
if (node.type === "workflow" && node.workflowId === WORKFLOW_ARM_SUBRUN_ID) {
|
|
@@ -3592,6 +4276,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3592
4276
|
}
|
|
3593
4277
|
checkId(singleId(node), path25);
|
|
3594
4278
|
checkPolicyEnums(node, path25);
|
|
4279
|
+
checkInputShape(node, path25);
|
|
3595
4280
|
checkTimeout(node, path25);
|
|
3596
4281
|
checkTier(node, path25);
|
|
3597
4282
|
checkRetry(node, path25);
|
|
@@ -3672,6 +4357,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3672
4357
|
const checkArm = /* @__PURE__ */ __name3((arm, path25, depth, container) => {
|
|
3673
4358
|
if (arm.type === "mapping") {
|
|
3674
4359
|
checkId(arm.id, path25);
|
|
4360
|
+
checkMapMembers(readMapConfig(arm.mapConfig), `${path25}.mapConfig`, arm.id);
|
|
3675
4361
|
for (const ref of nodeStepRefs(arm)) {
|
|
3676
4362
|
if (!upstream.has(ref)) err("template-reference-unresolved", `"${arm.id}" references stepResults.${ref}, which is not upstream`, path25, arm.id);
|
|
3677
4363
|
}
|
|
@@ -3696,6 +4382,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
3696
4382
|
break;
|
|
3697
4383
|
case "mapping":
|
|
3698
4384
|
checkId(entry.id, path25);
|
|
4385
|
+
checkMapMembers(readMapConfig(entry.mapConfig), `${path25}.mapConfig`, entry.id);
|
|
3699
4386
|
for (const ref of nodeStepRefs(entry)) {
|
|
3700
4387
|
if (!upstream.has(ref)) err("template-reference-unresolved", `"${entry.id}" references stepResults.${ref}, which is not upstream`, path25, entry.id);
|
|
3701
4388
|
}
|
|
@@ -4294,172 +4981,6 @@ function toPathOrLiteral(v) {
|
|
|
4294
4981
|
literal: v
|
|
4295
4982
|
};
|
|
4296
4983
|
}
|
|
4297
|
-
function isMapConfigObject(v) {
|
|
4298
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4299
|
-
}
|
|
4300
|
-
function parseMapConfig(raw, stepId) {
|
|
4301
|
-
if (isMapConfigObject(raw)) return raw;
|
|
4302
|
-
if (typeof raw !== "string") {
|
|
4303
|
-
throw new Error(`Stored mapping step "${stepId}" has a mapConfig that is neither a JSON string nor an object.`);
|
|
4304
|
-
}
|
|
4305
|
-
try {
|
|
4306
|
-
return JSON.parse(raw);
|
|
4307
|
-
} catch (e) {
|
|
4308
|
-
throw new Error(`Stored mapping step "${stepId}" has invalid JSON mapConfig: ${e.message}`);
|
|
4309
|
-
}
|
|
4310
|
-
}
|
|
4311
|
-
function mapConfigWire(raw) {
|
|
4312
|
-
if (typeof raw === "string") return raw;
|
|
4313
|
-
if (isMapConfigObject(raw)) return canonicalJson(raw);
|
|
4314
|
-
return void 0;
|
|
4315
|
-
}
|
|
4316
|
-
function describeBadPlaceholder(template22, idx, rawExpr) {
|
|
4317
|
-
return `Template placeholder #${idx} (\${${rawExpr}}) in '${template22}'`;
|
|
4318
|
-
}
|
|
4319
|
-
function parseTemplatePlaceholder(rawExpr) {
|
|
4320
|
-
const dot = rawExpr.indexOf(".");
|
|
4321
|
-
return {
|
|
4322
|
-
scope: dot === -1 ? rawExpr : rawExpr.slice(0, dot),
|
|
4323
|
-
rest: dot === -1 ? "" : rawExpr.slice(dot + 1)
|
|
4324
|
-
};
|
|
4325
|
-
}
|
|
4326
|
-
function traverseMappingPath(root, path25, errorLabel2) {
|
|
4327
|
-
if (path25 === "" || path25 === ".") return root;
|
|
4328
|
-
const parts = path25.split(".");
|
|
4329
|
-
let value22 = root;
|
|
4330
|
-
for (const part of parts) {
|
|
4331
|
-
if (typeof value22 === "object" && value22 !== null) value22 = value22[part];
|
|
4332
|
-
else throw new WorkflowTemplateError(`Invalid path ${path25} in ${errorLabel2}`, path25);
|
|
4333
|
-
}
|
|
4334
|
-
return value22;
|
|
4335
|
-
}
|
|
4336
|
-
function stringifyTemplateValue(v, template22, idx, rawExpr) {
|
|
4337
|
-
if (v === null || v === void 0) return "";
|
|
4338
|
-
if (typeof v === "object") {
|
|
4339
|
-
try {
|
|
4340
|
-
return JSON.stringify(v);
|
|
4341
|
-
} catch (err) {
|
|
4342
|
-
throw new WorkflowTemplateError(`${describeBadPlaceholder(template22, idx, rawExpr)} resolved to a value that could not be JSON-stringified (${err.message}).`, rawExpr);
|
|
4343
|
-
}
|
|
4344
|
-
}
|
|
4345
|
-
return String(v);
|
|
4346
|
-
}
|
|
4347
|
-
function escapeFence(content) {
|
|
4348
|
-
return content.replace(/<\/lua-data/g, "<\\/lua-data");
|
|
4349
|
-
}
|
|
4350
|
-
function fenceBlock(name, source, content) {
|
|
4351
|
-
return `<lua-data name="${name}" source="${source}" untrusted="true">${escapeFence(content)}</lua-data>`;
|
|
4352
|
-
}
|
|
4353
|
-
function renderTemplate(template22, ctx, opts) {
|
|
4354
|
-
let idx = 0;
|
|
4355
|
-
return template22.replace(TEMPLATE_PLACEHOLDER, (_match, rawExpr) => {
|
|
4356
|
-
idx += 1;
|
|
4357
|
-
const { scope, rest } = parseTemplatePlaceholder(rawExpr);
|
|
4358
|
-
const label = describeBadPlaceholder(template22, idx, rawExpr);
|
|
4359
|
-
let rendered;
|
|
4360
|
-
let source;
|
|
4361
|
-
switch (scope) {
|
|
4362
|
-
case "initData":
|
|
4363
|
-
rendered = stringifyTemplateValue(traverseMappingPath(ctx.initData, rest, label), template22, idx, rawExpr);
|
|
4364
|
-
source = "initData";
|
|
4365
|
-
break;
|
|
4366
|
-
case "state":
|
|
4367
|
-
rendered = stringifyTemplateValue(traverseMappingPath(ctx.state, rest, label), template22, idx, rawExpr);
|
|
4368
|
-
source = "state";
|
|
4369
|
-
break;
|
|
4370
|
-
case "requestContext":
|
|
4371
|
-
rendered = stringifyTemplateValue(traverseMappingPath(ctx.requestContext, rest, label), template22, idx, rawExpr);
|
|
4372
|
-
source = "requestContext";
|
|
4373
|
-
break;
|
|
4374
|
-
case "stepResults": {
|
|
4375
|
-
const innerDot = rest.indexOf(".");
|
|
4376
|
-
const stepId = innerDot === -1 ? rest : rest.slice(0, innerDot);
|
|
4377
|
-
const subPath = innerDot === -1 ? "" : rest.slice(innerDot + 1);
|
|
4378
|
-
if (!stepId) throw new WorkflowTemplateError(`${label} must name a step: \${stepResults.<stepId>.<path>}.`, rawExpr);
|
|
4379
|
-
if (!(stepId in ctx.stepResults) || ctx.stepResults[stepId] == null) {
|
|
4380
|
-
throw new WorkflowTemplateError(`${label} references stepResults.${stepId} but step "${stepId}" has no resolvable output (not an ancestor, not run, failed, or produced no output).`, rawExpr);
|
|
4381
|
-
}
|
|
4382
|
-
rendered = stringifyTemplateValue(traverseMappingPath(ctx.stepResults[stepId], subPath, label), template22, idx, rawExpr);
|
|
4383
|
-
source = `step:${stepId}`;
|
|
4384
|
-
break;
|
|
4385
|
-
}
|
|
4386
|
-
default:
|
|
4387
|
-
throw new WorkflowTemplateError(`${label} references unknown namespace "${scope}". Use one of: ${TEMPLATE_NAMESPACES.join(", ")}.`, rawExpr);
|
|
4388
|
-
}
|
|
4389
|
-
return opts.fenced ? fenceBlock(rawExpr, source, rendered) : rendered;
|
|
4390
|
-
});
|
|
4391
|
-
}
|
|
4392
|
-
function resolveDescriptor(key, m, ctx) {
|
|
4393
|
-
try {
|
|
4394
|
-
if ("value" in m) return {
|
|
4395
|
-
value: m.value
|
|
4396
|
-
};
|
|
4397
|
-
if ("template" in m && typeof m.template === "string") {
|
|
4398
|
-
return {
|
|
4399
|
-
value: renderTemplate(m.template, ctx, {
|
|
4400
|
-
fenced: false
|
|
4401
|
-
})
|
|
4402
|
-
};
|
|
4403
|
-
}
|
|
4404
|
-
if ("knowledge" in m || "rows" in m && m.rows !== void 0) {
|
|
4405
|
-
return {
|
|
4406
|
-
error: "binding_unresolved",
|
|
4407
|
-
key
|
|
4408
|
-
};
|
|
4409
|
-
}
|
|
4410
|
-
if ("requestContextPath" in m) {
|
|
4411
|
-
const label = `requestContext path for key "${key}"`;
|
|
4412
|
-
return {
|
|
4413
|
-
value: traverseMappingPath(ctx.requestContext, m.requestContextPath, label)
|
|
4414
|
-
};
|
|
4415
|
-
}
|
|
4416
|
-
if ("path" in m) {
|
|
4417
|
-
const source = "initData" in m && m.initData ? "initData" : "step";
|
|
4418
|
-
if (source === "initData") {
|
|
4419
|
-
return {
|
|
4420
|
-
value: traverseMappingPath(ctx.initData, m.path, `initData for key "${key}"`)
|
|
4421
|
-
};
|
|
4422
|
-
}
|
|
4423
|
-
const stepRef = m.step;
|
|
4424
|
-
const candidates = Array.isArray(stepRef) ? stepRef : [
|
|
4425
|
-
stepRef
|
|
4426
|
-
];
|
|
4427
|
-
const stepId = candidates.find((s) => ctx.stepResults[s] !== void 0 && ctx.stepResults[s] !== null);
|
|
4428
|
-
if (stepId === void 0) return {
|
|
4429
|
-
error: "binding_unresolved",
|
|
4430
|
-
key
|
|
4431
|
-
};
|
|
4432
|
-
return {
|
|
4433
|
-
value: traverseMappingPath(ctx.stepResults[stepId], m.path, `step ${candidates.join("|")} for key "${key}"`)
|
|
4434
|
-
};
|
|
4435
|
-
}
|
|
4436
|
-
return {
|
|
4437
|
-
error: "binding_unresolved",
|
|
4438
|
-
key
|
|
4439
|
-
};
|
|
4440
|
-
} catch (err) {
|
|
4441
|
-
if (err instanceof WorkflowTemplateError) return {
|
|
4442
|
-
error: "binding_unresolved",
|
|
4443
|
-
key
|
|
4444
|
-
};
|
|
4445
|
-
throw err;
|
|
4446
|
-
}
|
|
4447
|
-
}
|
|
4448
|
-
function resolveMapping(cfg, ctx) {
|
|
4449
|
-
const keys = Object.keys(cfg);
|
|
4450
|
-
if (keys.length === 1 && keys[0] === "") {
|
|
4451
|
-
return resolveDescriptor("", cfg[""], ctx);
|
|
4452
|
-
}
|
|
4453
|
-
const result = {};
|
|
4454
|
-
for (const key of keys) {
|
|
4455
|
-
const resolved = resolveDescriptor(key, cfg[key], ctx);
|
|
4456
|
-
if ("error" in resolved) return resolved;
|
|
4457
|
-
result[key] = resolved.value;
|
|
4458
|
-
}
|
|
4459
|
-
return {
|
|
4460
|
-
value: result
|
|
4461
|
-
};
|
|
4462
|
-
}
|
|
4463
4984
|
function continuedFailureValue(error, killReason) {
|
|
4464
4985
|
const code = typeof error?.code === "string" && error.code || typeof killReason === "string" && killReason || CONTINUED_FAILURE_DEFAULT_CODE;
|
|
4465
4986
|
const message = typeof error?.message === "string" && error.message ? error.message : code;
|
|
@@ -5094,15 +5615,64 @@ function runCounts(counts) {
|
|
|
5094
5615
|
pending: n(c.pending) + n(c.ready) + n(c.waiting)
|
|
5095
5616
|
};
|
|
5096
5617
|
}
|
|
5097
|
-
function
|
|
5618
|
+
function isPricedStepReceipt(receipt) {
|
|
5619
|
+
return typeof receipt?.multiplier === "number" && Number.isFinite(receipt.multiplier);
|
|
5620
|
+
}
|
|
5621
|
+
function receiptEngine(engine) {
|
|
5622
|
+
if (engine === "actions") return "seat";
|
|
5623
|
+
if (engine === "credits") return "legacy";
|
|
5624
|
+
return void 0;
|
|
5625
|
+
}
|
|
5626
|
+
function receiptTier(tier) {
|
|
5627
|
+
return tier === "light" || tier === "standard" || tier === "heavy" ? tier : void 0;
|
|
5628
|
+
}
|
|
5629
|
+
function stepBillingView(receipt) {
|
|
5630
|
+
const engine = receiptEngine(receipt?.engine);
|
|
5631
|
+
if (!receipt || engine === void 0) return void 0;
|
|
5632
|
+
return pruneUndefined({
|
|
5633
|
+
engine,
|
|
5634
|
+
attempt: typeof receipt.attempt === "number" ? receipt.attempt : void 0,
|
|
5635
|
+
credits: typeof receipt.credits === "number" ? receipt.credits : void 0,
|
|
5636
|
+
actions: typeof receipt.actionsEstimate === "number" ? receipt.actionsEstimate : void 0,
|
|
5637
|
+
model: typeof receipt.model === "string" ? receipt.model : void 0,
|
|
5638
|
+
tier: receiptTier(receipt.tier),
|
|
5639
|
+
multiplier: typeof receipt.multiplier === "number" ? receipt.multiplier : void 0,
|
|
5640
|
+
byok: typeof receipt.byok === "boolean" ? receipt.byok : void 0,
|
|
5641
|
+
calibrated: typeof receipt.calibrated === "boolean" ? receipt.calibrated : void 0
|
|
5642
|
+
});
|
|
5643
|
+
}
|
|
5644
|
+
function runUsage(run, receipts) {
|
|
5645
|
+
const actions = n(run.budget?.spent?.actionsEstimate);
|
|
5646
|
+
const stamped = run.budget?.engine;
|
|
5647
|
+
const priced = (receipts ?? []).filter(isPricedStepReceipt);
|
|
5648
|
+
const engine = stamped === "seat" || stamped === "legacy" ? stamped : actions > 0 || priced.some((r) => r.engine === "actions") ? "seat" : priced.some((r) => r.engine === "credits") ? "legacy" : void 0;
|
|
5649
|
+
const seat = engine === "seat";
|
|
5650
|
+
const metering = engine ? "priced" : "flat";
|
|
5098
5651
|
return {
|
|
5099
5652
|
creditsUsed: run.budget?.spent?.credits ?? 0,
|
|
5100
5653
|
actionsEstimate: run.budget?.spent?.actionsEstimate ?? 0,
|
|
5654
|
+
...seat ? {
|
|
5655
|
+
actionsUsed: actions
|
|
5656
|
+
} : {},
|
|
5657
|
+
metering,
|
|
5658
|
+
...engine ? {
|
|
5659
|
+
engine
|
|
5660
|
+
} : {},
|
|
5101
5661
|
steps: run.budget?.spent?.steps ?? 0,
|
|
5102
5662
|
inputTokens: run.usage?.inputTokens ?? 0,
|
|
5103
5663
|
outputTokens: run.usage?.outputTokens ?? 0
|
|
5104
5664
|
};
|
|
5105
5665
|
}
|
|
5666
|
+
function runBudgetCap(budget) {
|
|
5667
|
+
const cap = budget?.maxCredits;
|
|
5668
|
+
return typeof cap === "number" && Number.isFinite(cap) && cap > 0 ? cap : void 0;
|
|
5669
|
+
}
|
|
5670
|
+
function runBudgetRemaining(budget) {
|
|
5671
|
+
const cap = runBudgetCap(budget);
|
|
5672
|
+
if (cap === void 0) return void 0;
|
|
5673
|
+
const spent = budget?.spent;
|
|
5674
|
+
return Math.max(0, cap - n(spent?.credits) - n(spent?.actionsEstimate) - n(budget?.reserved));
|
|
5675
|
+
}
|
|
5106
5676
|
function runCancelView(cancel) {
|
|
5107
5677
|
if (!cancel) return void 0;
|
|
5108
5678
|
return {
|
|
@@ -6121,7 +6691,7 @@ function needsInheritedWorkspace(graph) {
|
|
|
6121
6691
|
}
|
|
6122
6692
|
return false;
|
|
6123
6693
|
}
|
|
6124
|
-
var __defProp3, __name3, SideEffectsSchema, JobResourcesSchema, WORKFLOW_ARM_SUBRUN_ID, WORKSPACE_TEMPLATE_EXPR_RE, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_TOOLS, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, isHitlNode, isSingleStep, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, isArmStep, armStepId, armStepKind, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not,
|
|
6694
|
+
var __defProp3, __name3, WorkflowTemplateError, TEMPLATE_PLACEHOLDER, TEMPLATE_NAMESPACES, MAP_DESCRIPTOR_KEYS, MAP_MEMBER_MALFORMED_CODE, fromInit, fromStep, value, template, fromRequest, rows, fromKnowledge, SideEffectsSchema, JobResourcesSchema, WORKFLOW_ARM_SUBRUN_ID, WORKSPACE_TEMPLATE_EXPR_RE, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_TOOLS, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, isHitlNode, isSingleStep, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, isArmStep, armStepId, armStepKind, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not, CONTINUED_FAILURE_TAG, CONTINUED_FAILURE_DEFAULT_CODE, CONTINUED_FAILURE_OUTPUT_SCHEMA, CONTINUED_FAILURE_LEAF_PATHS, isHitlNode2, nodeIdOf, GOAL_JUDGE_STEP_ID, NON_LEAF_KINDS, CONDITIONAL_JOIN_ID, branchArmId, canonical, sortKeys, JOIN, entryOfJoin, FORCE_CANCEL_STALE_MS, TERMINAL, IN_FLIGHT, n, STEP_ERROR_DETAIL_KEYS, STEP_ERROR_DETAIL_MAX_BYTES, DETAIL_MAX_DEPTH, DETAIL_MAX_ITEMS, MAX_HOLIDAYS, MAX_WALK_DAYS, HHMM, YMD, MS_PER_MIN, MS_PER_DAY, MON_FRI, supportedTz, fmtCache, WEEKDAYS, JSON_PATCH_OPS, JSON_PATCH_MAX_OPS, JSON_PATCH_MAX_VALUE_BYTES, JSON_PATCH_MAX_TOTAL_BYTES, SEGMENT_RE, APPROVER_SPEC_MAX_USERS, ESCALATION_MAX_HOPS, TemplateBindingSchema, ApproverSpecSchema, FourEyesSchema, EscalationHopSchema, TerminalOutcomeSchema, ApprovalOnTimeoutSchema, APPROVER_SPEC_SHAPES, APPROVER_WRITTEN_MAX, USER_ID_SHAPED_RE, BINDING_ROOTS, WORKFLOW_ENV_OVERLAY_MAX_KEYS, WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES, WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE, isEnvRef, looksLikeEmbeddedJson, ZERO, isRecord2;
|
|
6125
6695
|
var init_dist2 = __esm({
|
|
6126
6696
|
"../workflow-graph/dist/index.mjs"() {
|
|
6127
6697
|
"use strict";
|
|
@@ -6134,6 +6704,94 @@ var init_dist2 = __esm({
|
|
|
6134
6704
|
init_dist();
|
|
6135
6705
|
__defProp3 = Object.defineProperty;
|
|
6136
6706
|
__name3 = /* @__PURE__ */ __name((target, value22) => __defProp3(target, "name", { value: value22, configurable: true }), "__name");
|
|
6707
|
+
WorkflowTemplateError = class extends Error {
|
|
6708
|
+
static {
|
|
6709
|
+
__name(this, "WorkflowTemplateError");
|
|
6710
|
+
}
|
|
6711
|
+
static {
|
|
6712
|
+
__name3(this, "WorkflowTemplateError");
|
|
6713
|
+
}
|
|
6714
|
+
placeholder;
|
|
6715
|
+
constructor(message, placeholder) {
|
|
6716
|
+
super(message), this.placeholder = placeholder;
|
|
6717
|
+
this.name = "WorkflowTemplateError";
|
|
6718
|
+
}
|
|
6719
|
+
};
|
|
6720
|
+
__name(isMapConfigObject, "isMapConfigObject");
|
|
6721
|
+
__name3(isMapConfigObject, "isMapConfigObject");
|
|
6722
|
+
__name(parseMapConfig, "parseMapConfig");
|
|
6723
|
+
__name3(parseMapConfig, "parseMapConfig");
|
|
6724
|
+
__name(mapConfigWire, "mapConfigWire");
|
|
6725
|
+
__name3(mapConfigWire, "mapConfigWire");
|
|
6726
|
+
TEMPLATE_PLACEHOLDER = /\$\{([^}]*)\}/g;
|
|
6727
|
+
TEMPLATE_NAMESPACES = [
|
|
6728
|
+
"initData",
|
|
6729
|
+
"state",
|
|
6730
|
+
"requestContext",
|
|
6731
|
+
"stepResults"
|
|
6732
|
+
];
|
|
6733
|
+
__name(describeBadPlaceholder, "describeBadPlaceholder");
|
|
6734
|
+
__name3(describeBadPlaceholder, "describeBadPlaceholder");
|
|
6735
|
+
__name(parseTemplatePlaceholder, "parseTemplatePlaceholder");
|
|
6736
|
+
__name3(parseTemplatePlaceholder, "parseTemplatePlaceholder");
|
|
6737
|
+
__name(traverseMappingPath, "traverseMappingPath");
|
|
6738
|
+
__name3(traverseMappingPath, "traverseMappingPath");
|
|
6739
|
+
__name(stringifyTemplateValue, "stringifyTemplateValue");
|
|
6740
|
+
__name3(stringifyTemplateValue, "stringifyTemplateValue");
|
|
6741
|
+
__name(escapeFence, "escapeFence");
|
|
6742
|
+
__name3(escapeFence, "escapeFence");
|
|
6743
|
+
__name(fenceBlock, "fenceBlock");
|
|
6744
|
+
__name3(fenceBlock, "fenceBlock");
|
|
6745
|
+
__name(renderTemplate, "renderTemplate");
|
|
6746
|
+
__name3(renderTemplate, "renderTemplate");
|
|
6747
|
+
__name(isMapDescriptor, "isMapDescriptor");
|
|
6748
|
+
__name3(isMapDescriptor, "isMapDescriptor");
|
|
6749
|
+
MAP_DESCRIPTOR_KEYS = [
|
|
6750
|
+
"step",
|
|
6751
|
+
"path",
|
|
6752
|
+
"initData",
|
|
6753
|
+
"value",
|
|
6754
|
+
"template",
|
|
6755
|
+
"requestContextPath",
|
|
6756
|
+
"knowledge"
|
|
6757
|
+
];
|
|
6758
|
+
MAP_MEMBER_MALFORMED_CODE = "map-member-malformed";
|
|
6759
|
+
__name(malformedMapMembers, "malformedMapMembers");
|
|
6760
|
+
__name3(malformedMapMembers, "malformedMapMembers");
|
|
6761
|
+
__name(mapMemberMalformedMessage, "mapMemberMalformedMessage");
|
|
6762
|
+
__name3(mapMemberMalformedMessage, "mapMemberMalformedMessage");
|
|
6763
|
+
__name(resolveDescriptor, "resolveDescriptor");
|
|
6764
|
+
__name3(resolveDescriptor, "resolveDescriptor");
|
|
6765
|
+
__name(resolveMapping, "resolveMapping");
|
|
6766
|
+
__name3(resolveMapping, "resolveMapping");
|
|
6767
|
+
fromInit = /* @__PURE__ */ __name3((path25) => ({
|
|
6768
|
+
initData: true,
|
|
6769
|
+
path: path25
|
|
6770
|
+
}), "fromInit");
|
|
6771
|
+
fromStep = /* @__PURE__ */ __name3((s, path25 = "") => {
|
|
6772
|
+
const idOf = /* @__PURE__ */ __name3((x) => typeof x === "string" ? x : x.id, "idOf");
|
|
6773
|
+
return {
|
|
6774
|
+
step: Array.isArray(s) ? s.map(idOf) : idOf(s),
|
|
6775
|
+
path: path25
|
|
6776
|
+
};
|
|
6777
|
+
}, "fromStep");
|
|
6778
|
+
value = /* @__PURE__ */ __name3((v) => ({
|
|
6779
|
+
value: v
|
|
6780
|
+
}), "value");
|
|
6781
|
+
template = /* @__PURE__ */ __name3((s) => ({
|
|
6782
|
+
template: s
|
|
6783
|
+
}), "template");
|
|
6784
|
+
fromRequest = /* @__PURE__ */ __name3((path25) => ({
|
|
6785
|
+
requestContextPath: path25
|
|
6786
|
+
}), "fromRequest");
|
|
6787
|
+
rows = /* @__PURE__ */ __name3((s, path25, page) => ({
|
|
6788
|
+
step: typeof s === "string" ? s : s.id,
|
|
6789
|
+
path: path25,
|
|
6790
|
+
rows: page
|
|
6791
|
+
}), "rows");
|
|
6792
|
+
fromKnowledge = /* @__PURE__ */ __name3((k) => ({
|
|
6793
|
+
knowledge: k
|
|
6794
|
+
}), "fromKnowledge");
|
|
6137
6795
|
SideEffectsSchema = z6.enum(WORKFLOW_SIDE_EFFECTS);
|
|
6138
6796
|
JobResourcesSchema = z6.enum(WORKFLOW_JOB_RESOURCES);
|
|
6139
6797
|
WORKFLOW_ARM_SUBRUN_ID = "$arm";
|
|
@@ -6377,78 +7035,6 @@ var init_dist2 = __esm({
|
|
|
6377
7035
|
op: "not",
|
|
6378
7036
|
arg
|
|
6379
7037
|
}), "not");
|
|
6380
|
-
WorkflowTemplateError = class extends Error {
|
|
6381
|
-
static {
|
|
6382
|
-
__name(this, "WorkflowTemplateError");
|
|
6383
|
-
}
|
|
6384
|
-
static {
|
|
6385
|
-
__name3(this, "WorkflowTemplateError");
|
|
6386
|
-
}
|
|
6387
|
-
placeholder;
|
|
6388
|
-
constructor(message, placeholder) {
|
|
6389
|
-
super(message), this.placeholder = placeholder;
|
|
6390
|
-
this.name = "WorkflowTemplateError";
|
|
6391
|
-
}
|
|
6392
|
-
};
|
|
6393
|
-
__name(isMapConfigObject, "isMapConfigObject");
|
|
6394
|
-
__name3(isMapConfigObject, "isMapConfigObject");
|
|
6395
|
-
__name(parseMapConfig, "parseMapConfig");
|
|
6396
|
-
__name3(parseMapConfig, "parseMapConfig");
|
|
6397
|
-
__name(mapConfigWire, "mapConfigWire");
|
|
6398
|
-
__name3(mapConfigWire, "mapConfigWire");
|
|
6399
|
-
TEMPLATE_PLACEHOLDER = /\$\{([^}]*)\}/g;
|
|
6400
|
-
TEMPLATE_NAMESPACES = [
|
|
6401
|
-
"initData",
|
|
6402
|
-
"state",
|
|
6403
|
-
"requestContext",
|
|
6404
|
-
"stepResults"
|
|
6405
|
-
];
|
|
6406
|
-
__name(describeBadPlaceholder, "describeBadPlaceholder");
|
|
6407
|
-
__name3(describeBadPlaceholder, "describeBadPlaceholder");
|
|
6408
|
-
__name(parseTemplatePlaceholder, "parseTemplatePlaceholder");
|
|
6409
|
-
__name3(parseTemplatePlaceholder, "parseTemplatePlaceholder");
|
|
6410
|
-
__name(traverseMappingPath, "traverseMappingPath");
|
|
6411
|
-
__name3(traverseMappingPath, "traverseMappingPath");
|
|
6412
|
-
__name(stringifyTemplateValue, "stringifyTemplateValue");
|
|
6413
|
-
__name3(stringifyTemplateValue, "stringifyTemplateValue");
|
|
6414
|
-
__name(escapeFence, "escapeFence");
|
|
6415
|
-
__name3(escapeFence, "escapeFence");
|
|
6416
|
-
__name(fenceBlock, "fenceBlock");
|
|
6417
|
-
__name3(fenceBlock, "fenceBlock");
|
|
6418
|
-
__name(renderTemplate, "renderTemplate");
|
|
6419
|
-
__name3(renderTemplate, "renderTemplate");
|
|
6420
|
-
__name(resolveDescriptor, "resolveDescriptor");
|
|
6421
|
-
__name3(resolveDescriptor, "resolveDescriptor");
|
|
6422
|
-
__name(resolveMapping, "resolveMapping");
|
|
6423
|
-
__name3(resolveMapping, "resolveMapping");
|
|
6424
|
-
fromInit = /* @__PURE__ */ __name3((path25) => ({
|
|
6425
|
-
initData: true,
|
|
6426
|
-
path: path25
|
|
6427
|
-
}), "fromInit");
|
|
6428
|
-
fromStep = /* @__PURE__ */ __name3((s, path25 = "") => {
|
|
6429
|
-
const idOf = /* @__PURE__ */ __name3((x) => typeof x === "string" ? x : x.id, "idOf");
|
|
6430
|
-
return {
|
|
6431
|
-
step: Array.isArray(s) ? s.map(idOf) : idOf(s),
|
|
6432
|
-
path: path25
|
|
6433
|
-
};
|
|
6434
|
-
}, "fromStep");
|
|
6435
|
-
value = /* @__PURE__ */ __name3((v) => ({
|
|
6436
|
-
value: v
|
|
6437
|
-
}), "value");
|
|
6438
|
-
template = /* @__PURE__ */ __name3((s) => ({
|
|
6439
|
-
template: s
|
|
6440
|
-
}), "template");
|
|
6441
|
-
fromRequest = /* @__PURE__ */ __name3((path25) => ({
|
|
6442
|
-
requestContextPath: path25
|
|
6443
|
-
}), "fromRequest");
|
|
6444
|
-
rows = /* @__PURE__ */ __name3((s, path25, page) => ({
|
|
6445
|
-
step: typeof s === "string" ? s : s.id,
|
|
6446
|
-
path: path25,
|
|
6447
|
-
rows: page
|
|
6448
|
-
}), "rows");
|
|
6449
|
-
fromKnowledge = /* @__PURE__ */ __name3((k) => ({
|
|
6450
|
-
knowledge: k
|
|
6451
|
-
}), "fromKnowledge");
|
|
6452
7038
|
CONTINUED_FAILURE_TAG = "continued_failure";
|
|
6453
7039
|
CONTINUED_FAILURE_DEFAULT_CODE = "step_failed";
|
|
6454
7040
|
CONTINUED_FAILURE_OUTPUT_SCHEMA = Object.freeze({
|
|
@@ -6574,8 +7160,20 @@ var init_dist2 = __esm({
|
|
|
6574
7160
|
n = /* @__PURE__ */ __name3((v) => typeof v === "number" && Number.isFinite(v) ? v : 0, "n");
|
|
6575
7161
|
__name(runCounts, "runCounts");
|
|
6576
7162
|
__name3(runCounts, "runCounts");
|
|
7163
|
+
__name(isPricedStepReceipt, "isPricedStepReceipt");
|
|
7164
|
+
__name3(isPricedStepReceipt, "isPricedStepReceipt");
|
|
7165
|
+
__name(receiptEngine, "receiptEngine");
|
|
7166
|
+
__name3(receiptEngine, "receiptEngine");
|
|
7167
|
+
__name(receiptTier, "receiptTier");
|
|
7168
|
+
__name3(receiptTier, "receiptTier");
|
|
7169
|
+
__name(stepBillingView, "stepBillingView");
|
|
7170
|
+
__name3(stepBillingView, "stepBillingView");
|
|
6577
7171
|
__name(runUsage, "runUsage");
|
|
6578
7172
|
__name3(runUsage, "runUsage");
|
|
7173
|
+
__name(runBudgetCap, "runBudgetCap");
|
|
7174
|
+
__name3(runBudgetCap, "runBudgetCap");
|
|
7175
|
+
__name(runBudgetRemaining, "runBudgetRemaining");
|
|
7176
|
+
__name3(runBudgetRemaining, "runBudgetRemaining");
|
|
6579
7177
|
__name(runCancelView, "runCancelView");
|
|
6580
7178
|
__name3(runCancelView, "runCancelView");
|
|
6581
7179
|
__name(runWorkspaceView, "runWorkspaceView");
|
|
@@ -7060,6 +7658,7 @@ var init_workflow = __esm({
|
|
|
7060
7658
|
}, "assertPredicate");
|
|
7061
7659
|
assertRetry = /* @__PURE__ */ __name((r, id) => {
|
|
7062
7660
|
if (!r) return;
|
|
7661
|
+
if (typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS) throw new LuaWorkflowBuildError("cap-exceeded", `"${id}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
|
|
7063
7662
|
if (r.backoff !== void 0 && !WORKFLOW_RETRY_BACKOFFS.includes(r.backoff)) throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.backoff must be ${WORKFLOW_RETRY_BACKOFFS.map((b) => `'${b}'`).join(" | ")}`);
|
|
7064
7663
|
if (r.maxBackoffSeconds !== void 0) {
|
|
7065
7664
|
if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${id}": retry.maxBackoffSeconds is only meaningful with backoff:'exponential'`);
|
|
@@ -7970,6 +8569,10 @@ async function* parseSseStream(body, signal) {
|
|
|
7970
8569
|
if (frame) yield frame;
|
|
7971
8570
|
}
|
|
7972
8571
|
} finally {
|
|
8572
|
+
try {
|
|
8573
|
+
await reader.cancel();
|
|
8574
|
+
} catch {
|
|
8575
|
+
}
|
|
7973
8576
|
try {
|
|
7974
8577
|
reader.releaseLock();
|
|
7975
8578
|
} catch {
|
|
@@ -7999,6 +8602,7 @@ var init_http_client = __esm({
|
|
|
7999
8602
|
"use strict";
|
|
8000
8603
|
init_dist();
|
|
8001
8604
|
init_auth_error();
|
|
8605
|
+
init_cli_error();
|
|
8002
8606
|
init_lua_fetch();
|
|
8003
8607
|
init_request_credential();
|
|
8004
8608
|
DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
@@ -8062,7 +8666,7 @@ var init_http_client = __esm({
|
|
|
8062
8666
|
if (AuthenticationError.isAuthenticationError(error)) {
|
|
8063
8667
|
throw error;
|
|
8064
8668
|
}
|
|
8065
|
-
if (error
|
|
8669
|
+
if (isAccessDeniedError(error)) {
|
|
8066
8670
|
throw error;
|
|
8067
8671
|
}
|
|
8068
8672
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
@@ -8110,8 +8714,11 @@ var init_http_client = __esm({
|
|
|
8110
8714
|
}
|
|
8111
8715
|
if (response.status === 403) {
|
|
8112
8716
|
const detail = errorData.message || "You do not have permission to access this resource.";
|
|
8113
|
-
throw new
|
|
8114
|
-
|
|
8717
|
+
throw new CliError("forbidden", `Access denied (403): ${detail}`, {
|
|
8718
|
+
exitCode: CLI_EXIT.FORBIDDEN,
|
|
8719
|
+
statusCode: 403,
|
|
8720
|
+
hint: "Check that your Lua login has access to this agent or organization."
|
|
8721
|
+
});
|
|
8115
8722
|
}
|
|
8116
8723
|
return {
|
|
8117
8724
|
success: false,
|
|
@@ -9379,6 +9986,7 @@ var init_base_handler = __esm({
|
|
|
9379
9986
|
init_bundle_upload();
|
|
9380
9987
|
init_semver();
|
|
9381
9988
|
init_auth_error();
|
|
9989
|
+
init_cli_error();
|
|
9382
9990
|
DEFAULT_VERSION = SKILL_DEFAULTS.VERSION;
|
|
9383
9991
|
BaseVersionedHandler = class {
|
|
9384
9992
|
static {
|
|
@@ -9460,7 +10068,7 @@ var init_base_handler = __esm({
|
|
|
9460
10068
|
serverItems
|
|
9461
10069
|
};
|
|
9462
10070
|
} catch (error) {
|
|
9463
|
-
if (AuthenticationError.isAuthenticationError(error)) throw error;
|
|
10071
|
+
if (AuthenticationError.isAuthenticationError(error) || isAccessDeniedError(error)) throw error;
|
|
9464
10072
|
return {
|
|
9465
10073
|
serverItems: null,
|
|
9466
10074
|
fetchError: error instanceof Error ? error.message : String(error)
|
|
@@ -9490,13 +10098,24 @@ var init_base_handler = __esm({
|
|
|
9490
10098
|
}
|
|
9491
10099
|
const yamlItems = this.getFromYaml(config);
|
|
9492
10100
|
const { yamlById, yamlByName, serverByName } = this.buildMaps(serverData.serverItems, yamlItems);
|
|
10101
|
+
const idField = this.yamlConfig.idField;
|
|
10102
|
+
const manifestNames = manifest ? new Set(getPrimitivesByKind(manifest, this.kind).map((p) => p.name)) : /* @__PURE__ */ new Set();
|
|
10103
|
+
for (const stale of this.staleYamlRows(yamlItems, serverData.serverItems, manifestNames)) {
|
|
10104
|
+
const idx = yamlItems.indexOf(stale);
|
|
10105
|
+
if (idx < 0) continue;
|
|
10106
|
+
const { [idField]: goneId, ...rest } = stale;
|
|
10107
|
+
yamlItems[idx] = rest;
|
|
10108
|
+
yamlUpdated = true;
|
|
10109
|
+
const msg = `\u2139\uFE0F ${this.displayName} "${stale.name}" (${goneId}) no longer exists on the server \u2014 re-registering it`;
|
|
10110
|
+
messages.push(msg);
|
|
10111
|
+
console.log(msg);
|
|
10112
|
+
}
|
|
9493
10113
|
const orphans = serverData.serverItems.filter((item) => {
|
|
9494
10114
|
const id = item.id;
|
|
9495
10115
|
const name = item.name;
|
|
9496
10116
|
return !yamlById.has(id) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);
|
|
9497
10117
|
});
|
|
9498
10118
|
if (orphans.length > 0) {
|
|
9499
|
-
const idField = this.yamlConfig.idField;
|
|
9500
10119
|
const stubs = orphans.map((item) => this.cleanItem({
|
|
9501
10120
|
name: item.name,
|
|
9502
10121
|
version: this.getActiveVersion(item) || DEFAULT_VERSION,
|
|
@@ -9539,6 +10158,7 @@ var init_base_handler = __esm({
|
|
|
9539
10158
|
console.log(`\u2705 Server ${this.displayNamePlural} and YAML are fully in sync`);
|
|
9540
10159
|
}
|
|
9541
10160
|
} catch (error) {
|
|
10161
|
+
if (AuthenticationError.isAuthenticationError(error) || isAccessDeniedError(error)) throw error;
|
|
9542
10162
|
console.error(`\u274C Error syncing server ${this.displayNamePlural}:`, error);
|
|
9543
10163
|
}
|
|
9544
10164
|
return {
|
|
@@ -9595,6 +10215,7 @@ var init_base_handler = __esm({
|
|
|
9595
10215
|
console.error(` \u274C Failed to create "${item.name}" - no ID returned`);
|
|
9596
10216
|
}
|
|
9597
10217
|
} catch (error) {
|
|
10218
|
+
if (AuthenticationError.isAuthenticationError(error) || isAccessDeniedError(error)) throw error;
|
|
9598
10219
|
console.error(` \u274C Failed to create "${item.name}": ${error instanceof Error ? error.message : error}`);
|
|
9599
10220
|
}
|
|
9600
10221
|
}
|
|
@@ -9729,6 +10350,15 @@ var init_base_handler = __esm({
|
|
|
9729
10350
|
getItemId(item) {
|
|
9730
10351
|
return item[this.yamlConfig.idField] || "";
|
|
9731
10352
|
}
|
|
10353
|
+
/**
|
|
10354
|
+
* LUA-750: the yaml rows whose server id is gone (deleted server-side) and which `applySyncToYaml` should
|
|
10355
|
+
* re-register. Default none — a handler whose `fetchFromServer` lists EVERY live row of its kind for the
|
|
10356
|
+
* agent overrides this (a kind whose list omits inactive rows must not, or it would duplicate them).
|
|
10357
|
+
* `manifestNames` is the set of primitives in local code: only those are worth re-creating.
|
|
10358
|
+
*/
|
|
10359
|
+
staleYamlRows(_yamlItems, _serverItems, _manifestNames) {
|
|
10360
|
+
return [];
|
|
10361
|
+
}
|
|
9732
10362
|
buildMaps(serverItems, yamlItems) {
|
|
9733
10363
|
const yamlById = /* @__PURE__ */ new Map();
|
|
9734
10364
|
const yamlByName = /* @__PURE__ */ new Map();
|
|
@@ -9818,7 +10448,7 @@ var init_base_handler = __esm({
|
|
|
9818
10448
|
serverItems
|
|
9819
10449
|
};
|
|
9820
10450
|
} catch (error) {
|
|
9821
|
-
if (AuthenticationError.isAuthenticationError(error)) throw error;
|
|
10451
|
+
if (AuthenticationError.isAuthenticationError(error) || isAccessDeniedError(error)) throw error;
|
|
9822
10452
|
return {
|
|
9823
10453
|
serverItems: null,
|
|
9824
10454
|
fetchError: error instanceof Error ? error.message : String(error)
|
|
@@ -9887,6 +10517,7 @@ var init_base_handler = __esm({
|
|
|
9887
10517
|
console.log(`\u2705 Server ${this.displayNamePlural} and YAML are fully in sync`);
|
|
9888
10518
|
}
|
|
9889
10519
|
} catch (error) {
|
|
10520
|
+
if (AuthenticationError.isAuthenticationError(error) || isAccessDeniedError(error)) throw error;
|
|
9890
10521
|
console.error(`\u274C Error syncing server ${this.displayNamePlural}:`, error);
|
|
9891
10522
|
}
|
|
9892
10523
|
return {
|
|
@@ -10697,46 +11328,48 @@ async function withErrorHandling(commandFn, commandName, opts) {
|
|
|
10697
11328
|
});
|
|
10698
11329
|
await shutdownAnalytics();
|
|
10699
11330
|
process.exit(0);
|
|
11331
|
+
return void 0;
|
|
11332
|
+
}
|
|
11333
|
+
if (isHandledCliError(error)) {
|
|
11334
|
+
trackCommand({
|
|
11335
|
+
commandName,
|
|
11336
|
+
success: false,
|
|
11337
|
+
durationMs: Date.now() - startTime,
|
|
11338
|
+
cliVersion: getCliVersion(),
|
|
11339
|
+
error: error.message,
|
|
11340
|
+
properties: {
|
|
11341
|
+
is_auth_error: AuthenticationError.isAuthenticationError(error.original),
|
|
11342
|
+
nested: true
|
|
11343
|
+
}
|
|
11344
|
+
});
|
|
11345
|
+
await showUpdateWarningIfNeeded(versionCheckPromise);
|
|
11346
|
+
await shutdownAnalytics();
|
|
11347
|
+
throw error;
|
|
10700
11348
|
}
|
|
10701
11349
|
trackCommand({
|
|
10702
11350
|
commandName,
|
|
10703
11351
|
success: false,
|
|
10704
11352
|
durationMs: Date.now() - startTime,
|
|
10705
11353
|
cliVersion: getCliVersion(),
|
|
10706
|
-
error: error
|
|
11354
|
+
error: error?.message,
|
|
10707
11355
|
properties: {
|
|
10708
11356
|
is_auth_error: AuthenticationError.isAuthenticationError(error)
|
|
10709
11357
|
}
|
|
10710
11358
|
});
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
\u274C ${error.message}`);
|
|
10714
|
-
if (!error.suppressDefaultRemediation) {
|
|
10715
|
-
if (error.reason === "no_agent_access") {
|
|
10716
|
-
console.error("\n Your API key is valid, but it does not have access to the agentId\n configured in lua.skill.yaml. This usually means:\n\n \u2022 The agentId belongs to a different account or organization\n \u2022 The agent was deleted, transferred, or you lost access to it\n \u2022 You're using a lua.skill.yaml copied from another project\n\n Check the configured agent and switch if needed:\n\n \u279C lua agents (list agents you have access to)\n \u279C lua init (re-select the agent for this project)\n");
|
|
10717
|
-
} else {
|
|
10718
|
-
console.error("\n Re-authenticate or check your API key:\n\n \u279C lua auth configure\n \u279C https://admin.heylua.ai\n");
|
|
10719
|
-
}
|
|
10720
|
-
} else {
|
|
10721
|
-
console.error("");
|
|
10722
|
-
}
|
|
10723
|
-
await showUpdateWarningIfNeeded(versionCheckPromise);
|
|
10724
|
-
await shutdownAnalytics();
|
|
10725
|
-
process.exit(1);
|
|
10726
|
-
}
|
|
10727
|
-
console.error(`\u274C Error during ${commandName}:`, error.message);
|
|
10728
|
-
if (opts?.onError && !hintsDisabled()) {
|
|
11359
|
+
let extraHint;
|
|
11360
|
+
if (opts?.onError && !hintsDisabled() && !AuthenticationError.isAuthenticationError(error)) {
|
|
10729
11361
|
try {
|
|
10730
|
-
|
|
10731
|
-
if (hint) {
|
|
10732
|
-
console.error(`\u{1F4A1} ${hint}`);
|
|
10733
|
-
}
|
|
11362
|
+
extraHint = opts.onError(error) ?? void 0;
|
|
10734
11363
|
} catch {
|
|
10735
11364
|
}
|
|
10736
11365
|
}
|
|
11366
|
+
const reported = reportCliError(error, {
|
|
11367
|
+
extraHint
|
|
11368
|
+
});
|
|
11369
|
+
process.exitCode = reported.exitCode;
|
|
10737
11370
|
await showUpdateWarningIfNeeded(versionCheckPromise);
|
|
10738
11371
|
await shutdownAnalytics();
|
|
10739
|
-
throw new
|
|
11372
|
+
throw new HandledCliError(reported.message, reported.exitCode, error);
|
|
10740
11373
|
}
|
|
10741
11374
|
}
|
|
10742
11375
|
function clearPromptLines(count = 1) {
|
|
@@ -10755,6 +11388,7 @@ var init_cli = __esm({
|
|
|
10755
11388
|
"src/utils/cli.ts"() {
|
|
10756
11389
|
"use strict";
|
|
10757
11390
|
init_auth_error();
|
|
11391
|
+
init_cli_error();
|
|
10758
11392
|
init_version_check();
|
|
10759
11393
|
init_package_root();
|
|
10760
11394
|
init_analytics();
|
|
@@ -10856,6 +11490,15 @@ async function checkApiKey(apiKey) {
|
|
|
10856
11490
|
const authApi = new AuthApi(BASE_URLS.API);
|
|
10857
11491
|
const result = await authApi.checkApiKey(apiKey);
|
|
10858
11492
|
if (!result.success) {
|
|
11493
|
+
const status = result.error?.statusCode ?? 0;
|
|
11494
|
+
if (status === 0 || status >= 500) {
|
|
11495
|
+
const detail = result.error?.message ?? "no response";
|
|
11496
|
+
throw new CliError("unavailable", `Could not verify the API key \u2014 the Lua API at ${BASE_URLS.API} is unavailable (${detail})`, {
|
|
11497
|
+
exitCode: CLI_EXIT.UNAVAILABLE,
|
|
11498
|
+
statusCode: status,
|
|
11499
|
+
hint: UNAVAILABLE_HINT
|
|
11500
|
+
});
|
|
11501
|
+
}
|
|
10859
11502
|
throw new AuthenticationError("Invalid API key");
|
|
10860
11503
|
}
|
|
10861
11504
|
return result.data;
|
|
@@ -10886,6 +11529,7 @@ var init_auth = __esm({
|
|
|
10886
11529
|
init_auth_api_service();
|
|
10887
11530
|
init_constants();
|
|
10888
11531
|
init_auth_error();
|
|
11532
|
+
init_cli_error();
|
|
10889
11533
|
__name(getToken, "getToken");
|
|
10890
11534
|
__name(saveApiKey, "saveApiKey");
|
|
10891
11535
|
__name(checkApiKey, "checkApiKey");
|
|
@@ -10898,31 +11542,27 @@ var init_auth = __esm({
|
|
|
10898
11542
|
async function requireAuth() {
|
|
10899
11543
|
return resolveRequestCredential();
|
|
10900
11544
|
}
|
|
10901
|
-
async function requireAuthOrExit(
|
|
10902
|
-
|
|
10903
|
-
if (showProgress) {
|
|
10904
|
-
writeProgress("\u2705 Authenticated");
|
|
10905
|
-
}
|
|
10906
|
-
return apiKey;
|
|
11545
|
+
async function requireAuthOrExit(_showProgress = true) {
|
|
11546
|
+
return resolveRequestCredential();
|
|
10907
11547
|
}
|
|
10908
11548
|
async function initializeCommand(options = {}) {
|
|
10909
11549
|
const { showProgress = true, validateAuth = false } = options;
|
|
10910
11550
|
const config = readYamlConfig();
|
|
10911
11551
|
if (!config) {
|
|
10912
|
-
throw
|
|
11552
|
+
throw CliError.usage("No lua.skill.yaml found \u2014 run this command from a Lua project directory.", "lua init creates one");
|
|
10913
11553
|
}
|
|
10914
11554
|
if (!config.agent?.agentId) {
|
|
10915
|
-
throw
|
|
11555
|
+
throw CliError.usage("Missing agentId in lua.skill.yaml.", "Run 'lua init' to select the agent for this project");
|
|
10916
11556
|
}
|
|
10917
11557
|
if (!config.agent?.orgId) {
|
|
10918
|
-
throw
|
|
11558
|
+
throw CliError.usage("Missing orgId in lua.skill.yaml.", "Run 'lua init' to select the agent for this project");
|
|
10919
11559
|
}
|
|
10920
11560
|
const apiKey = await resolveRequestCredential();
|
|
10921
11561
|
let userData = void 0;
|
|
10922
11562
|
if (validateAuth) {
|
|
10923
11563
|
userData = await checkApiKey(await bearerFor(apiKey));
|
|
10924
11564
|
}
|
|
10925
|
-
if (showProgress) {
|
|
11565
|
+
if (showProgress && validateAuth) {
|
|
10926
11566
|
writeProgress("\u2705 Authenticated");
|
|
10927
11567
|
}
|
|
10928
11568
|
return {
|
|
@@ -10940,6 +11580,7 @@ var init_command_utils = __esm({
|
|
|
10940
11580
|
init_request_credential();
|
|
10941
11581
|
init_files();
|
|
10942
11582
|
init_cli();
|
|
11583
|
+
init_cli_error();
|
|
10943
11584
|
__name(requireAuth, "requireAuth");
|
|
10944
11585
|
__name(requireAuthOrExit, "requireAuthOrExit");
|
|
10945
11586
|
__name(initializeCommand, "initializeCommand");
|
|
@@ -24078,7 +24719,10 @@ var init_workflow_api_service = __esm({
|
|
|
24078
24719
|
async getRunReplayBundle(runId) {
|
|
24079
24720
|
return this.httpGet(`${this.runs}/${runId}/journal?format=replay`, await this.auth());
|
|
24080
24721
|
}
|
|
24081
|
-
/**
|
|
24722
|
+
/**
|
|
24723
|
+
* R11 — cancel (`mode:'request'` default). A `'force'` before `forceAvailableAt` is the 200 verdict
|
|
24724
|
+
* `{ transitioned:false, nextAction:'cancel_again', forceAvailableAt }` (PRO-979) — never a 409 (LUA-748).
|
|
24725
|
+
*/
|
|
24082
24726
|
async cancelRun(runId, data = {}) {
|
|
24083
24727
|
return this.httpPost(`${this.runs}/${runId}/cancel`, data, await this.auth());
|
|
24084
24728
|
}
|
|
@@ -24157,6 +24801,14 @@ var init_workflow_api_service = __esm({
|
|
|
24157
24801
|
async closeGoal(goalId, data = {}) {
|
|
24158
24802
|
return this.httpPost(`${this.goals}/${encodeURIComponent(goalId)}/close`, data, await this.auth());
|
|
24159
24803
|
}
|
|
24804
|
+
/** LUA-749 R63 — edit (objective / judge / cadence / caps / note); a `budget` / `max_runs` park re-arms when the cap clears (`rearmed:true`). */
|
|
24805
|
+
async updateGoal(goalId, data) {
|
|
24806
|
+
return this.httpPatch(`${this.goals}/${encodeURIComponent(goalId)}`, data, await this.auth());
|
|
24807
|
+
}
|
|
24808
|
+
/** LUA-749 R64 — raise `maxTotalCredits` / `maxRuns` (increases only; 400 `GOAL_RAISE_BELOW_SPENT{field, value, spent}`). */
|
|
24809
|
+
async raiseGoal(goalId, data) {
|
|
24810
|
+
return this.httpPost(`${this.goals}/${encodeURIComponent(goalId)}/raise`, data, await this.auth());
|
|
24811
|
+
}
|
|
24160
24812
|
// ─── Schedules (R4-MF-2 list/get + R28 delete — `/workflows/:agentId/schedules`; LUA-627 stanza) ───
|
|
24161
24813
|
/** Schedule tree (09 §9.5 — the write-only R27/R56/R28 family plus the R4-MF-2 read rows). */
|
|
24162
24814
|
get schedules() {
|
|
@@ -24170,7 +24822,7 @@ var init_workflow_api_service = __esm({
|
|
|
24170
24822
|
async getSchedule(jobId) {
|
|
24171
24823
|
return this.httpGet(`${this.schedules}/${encodeURIComponent(jobId)}`, await this.auth());
|
|
24172
24824
|
}
|
|
24173
|
-
/** R28 — delete a schedule Job (404 `SCHEDULE_NOT_FOUND`). The CLI refuses a goal
|
|
24825
|
+
/** R28 — delete a schedule Job (404 `SCHEDULE_NOT_FOUND`). The CLI refuses a LIVE goal's job BEFORE this call (`goal_schedule`); an ended goal's lingering Job is retired here (LUA-760). */
|
|
24174
24826
|
async deleteSchedule(jobId) {
|
|
24175
24827
|
return this.httpDelete(`${this.schedules}/${encodeURIComponent(jobId)}`, await this.auth());
|
|
24176
24828
|
}
|
|
@@ -25707,6 +26359,7 @@ __name(configureCommand, "configureCommand");
|
|
|
25707
26359
|
// src/commands/init.ts
|
|
25708
26360
|
import inquirer4 from "inquirer";
|
|
25709
26361
|
init_command_utils();
|
|
26362
|
+
init_cli_error();
|
|
25710
26363
|
init_cli();
|
|
25711
26364
|
import { writeFileSync as writeFileSync7, existsSync as existsSync8 } from "fs";
|
|
25712
26365
|
import { join as join8 } from "path";
|
|
@@ -27942,10 +28595,7 @@ function requireLegacyMutationCredential(credential, mutation) {
|
|
|
27942
28595
|
}
|
|
27943
28596
|
const action = mutation === "create" ? "create a new agent" : "duplicate an agent";
|
|
27944
28597
|
const message = `Scoped CLI credentials cannot ${action}. Use your renewable first-party session in the Lua dashboard, then rerun \`lua init --agent-id <id>\`.`;
|
|
27945
|
-
|
|
27946
|
-
\u274C ${message}`);
|
|
27947
|
-
writeInfo(" Dashboard: https://admin.heylua.ai\n");
|
|
27948
|
-
throw new Error(message);
|
|
28598
|
+
throw CliError.forbidden(message, "Dashboard: https://admin.heylua.ai");
|
|
27949
28599
|
}
|
|
27950
28600
|
__name(requireLegacyMutationCredential, "requireLegacyMutationCredential");
|
|
27951
28601
|
function toInitOrganizations(organizations) {
|
|
@@ -28274,9 +28924,8 @@ async function initCommand(options = {}) {
|
|
|
28274
28924
|
return withErrorHandling(async () => {
|
|
28275
28925
|
const mode = determineInitMode(options);
|
|
28276
28926
|
if (mode.type === "error") {
|
|
28277
|
-
console.error(`\u274C ${mode.message}`);
|
|
28278
28927
|
showInitUsage();
|
|
28279
|
-
throw
|
|
28928
|
+
throw CliError.usage(mode.message);
|
|
28280
28929
|
}
|
|
28281
28930
|
const isNonInteractive = mode.type !== "interactive";
|
|
28282
28931
|
const apiKey = await requireAuthOrExit(false);
|
|
@@ -28291,10 +28940,7 @@ async function initCommand(options = {}) {
|
|
|
28291
28940
|
const existingAgentId = existingYaml?.agent?.agentId;
|
|
28292
28941
|
if (existingAgentId) {
|
|
28293
28942
|
if (isNonInteractive && !options.force) {
|
|
28294
|
-
|
|
28295
|
-
writeInfo(` Current Agent ID: ${existingAgentId}`);
|
|
28296
|
-
writeInfo("\n\u{1F4A1} Use --force to override the existing configuration\n");
|
|
28297
|
-
throw new Error("Operation failed");
|
|
28943
|
+
throw CliError.usage(`Project already initialized with agent ${existingAgentId}`, "Pass --force to override the existing configuration");
|
|
28298
28944
|
}
|
|
28299
28945
|
if (isNonInteractive && options.force) {
|
|
28300
28946
|
writeInfo("\n\u{1F504} Overriding existing project configuration...\n");
|
|
@@ -31809,32 +32455,48 @@ function validateJsonSchema(schema, value3, at = "") {
|
|
|
31809
32455
|
return issues;
|
|
31810
32456
|
}
|
|
31811
32457
|
__name(validateJsonSchema, "validateJsonSchema");
|
|
31812
|
-
|
|
31813
|
-
|
|
31814
|
-
|
|
31815
|
-
|
|
31816
|
-
|
|
31817
|
-
|
|
31818
|
-
|
|
31819
|
-
if (
|
|
31820
|
-
|
|
31821
|
-
|
|
31822
|
-
|
|
31823
|
-
|
|
31824
|
-
|
|
31825
|
-
|
|
31826
|
-
|
|
31827
|
-
|
|
31828
|
-
|
|
31829
|
-
|
|
31830
|
-
|
|
31831
|
-
|
|
31832
|
-
|
|
31833
|
-
|
|
31834
|
-
|
|
31835
|
-
|
|
32458
|
+
var AGENT_REPLY_ENVELOPE_KEYS = /* @__PURE__ */ new Set([
|
|
32459
|
+
"text",
|
|
32460
|
+
"object"
|
|
32461
|
+
]);
|
|
32462
|
+
function isAgentReplyEnvelope(reply) {
|
|
32463
|
+
if (typeof reply !== "object" || reply === null || Array.isArray(reply)) return false;
|
|
32464
|
+
const keys = Object.keys(reply);
|
|
32465
|
+
if (keys.length === 0 || !keys.every((k) => AGENT_REPLY_ENVELOPE_KEYS.has(k))) return false;
|
|
32466
|
+
const text = reply.text;
|
|
32467
|
+
return text === void 0 || typeof text === "string";
|
|
32468
|
+
}
|
|
32469
|
+
__name(isAgentReplyEnvelope, "isAgentReplyEnvelope");
|
|
32470
|
+
function coerceAgentStepOutput(schema, reply) {
|
|
32471
|
+
const envelope = typeof reply === "string" ? {
|
|
32472
|
+
text: reply
|
|
32473
|
+
} : reply;
|
|
32474
|
+
if (!isAgentReplyEnvelope(envelope)) return {
|
|
32475
|
+
ok: true,
|
|
32476
|
+
output: reply
|
|
32477
|
+
};
|
|
32478
|
+
const { text, object } = envelope;
|
|
32479
|
+
if (object !== void 0) return {
|
|
32480
|
+
ok: true,
|
|
32481
|
+
output: object
|
|
32482
|
+
};
|
|
32483
|
+
if (!schema) return {
|
|
32484
|
+
ok: true,
|
|
32485
|
+
output: {
|
|
32486
|
+
text
|
|
32487
|
+
}
|
|
32488
|
+
};
|
|
32489
|
+
const extracted = extractSingleJsonValue(text ?? "");
|
|
32490
|
+
if ("reason" in extracted) return {
|
|
32491
|
+
ok: false,
|
|
32492
|
+
reason: extracted.reason
|
|
32493
|
+
};
|
|
32494
|
+
return {
|
|
32495
|
+
ok: true,
|
|
32496
|
+
output: extracted.value
|
|
32497
|
+
};
|
|
31836
32498
|
}
|
|
31837
|
-
__name(
|
|
32499
|
+
__name(coerceAgentStepOutput, "coerceAgentStepOutput");
|
|
31838
32500
|
var armId2 = /* @__PURE__ */ __name((arm) => arm.type === "step" ? arm.step.id : arm.id, "armId");
|
|
31839
32501
|
var baseIdOf = /* @__PURE__ */ __name((id) => id.replace(/(\[\d+\]|#\d+)$/, ""), "baseIdOf");
|
|
31840
32502
|
var outputSchemaOf = /* @__PURE__ */ __name((entry) => {
|
|
@@ -31966,10 +32628,6 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
31966
32628
|
if (!entry.editable && editable.length === 0) {
|
|
31967
32629
|
throw new WorkflowLocalUsageError("approval-not-editable", `--approve ${id}: the approval is not editable`, id);
|
|
31968
32630
|
}
|
|
31969
|
-
const bad = collectLeafPaths(answer.payload).filter((p) => !matchesEditablePath2(p, editable));
|
|
31970
|
-
if (bad.length) {
|
|
31971
|
-
throw new WorkflowLocalUsageError("edit-path-not-allowed", `--approve ${id}: path "${bad[0]}" is outside editablePaths [${editable.join(", ")}]`, id);
|
|
31972
|
-
}
|
|
31973
32631
|
if (entry.editedPayloadSchema) {
|
|
31974
32632
|
const issues = validateJsonSchema(entry.editedPayloadSchema, answer.payload);
|
|
31975
32633
|
if (issues.length) {
|
|
@@ -32300,6 +32958,63 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
32300
32958
|
if (!issues.length) return void 0;
|
|
32301
32959
|
return new StepFailure("input_schema_invalid", `input does not match inputSchema of "${single.step.id}" \u2014 the previous node does not emit what the step declares: ${issues.join("; ")}`);
|
|
32302
32960
|
}, "stepInputIssue");
|
|
32961
|
+
const agentReply = /* @__PURE__ */ __name(async (row2, single, input) => {
|
|
32962
|
+
const id = row2.stepId;
|
|
32963
|
+
const fixture = opts.fixturesDir ? readFixture(id, row2.attempt) : void 0;
|
|
32964
|
+
if (opts.fixturesDir) return fixture;
|
|
32965
|
+
const prompt = renderPrompt(single);
|
|
32966
|
+
if (opts.agents === "live") {
|
|
32967
|
+
if (!opts.agentInvoke) throw new StepFailure("AGENTS_LIVE_UNAVAILABLE", "--agents live needs a dev API session");
|
|
32968
|
+
const t0 = Date.now();
|
|
32969
|
+
const out = await withWall(id, single, () => opts.agentInvoke(single, prompt, input));
|
|
32970
|
+
record(id, row2.attempt, {
|
|
32971
|
+
prompt,
|
|
32972
|
+
input
|
|
32973
|
+
}, out, Date.now() - t0);
|
|
32974
|
+
return out;
|
|
32975
|
+
}
|
|
32976
|
+
if (single.tier === "job" && jobWallS !== void 0) {
|
|
32977
|
+
const segments = Math.max(1, Math.ceil(jobWallS / WORKFLOW_LOCAL_JOB_SEGMENT_MAX_S));
|
|
32978
|
+
let sessionRef;
|
|
32979
|
+
let elapsedS = 0;
|
|
32980
|
+
for (let s = 1; s <= segments; s++) {
|
|
32981
|
+
const wallS = Math.min(WORKFLOW_LOCAL_JOB_SEGMENT_MAX_S, jobWallS - elapsedS);
|
|
32982
|
+
elapsedS += wallS;
|
|
32983
|
+
clock += wallS * 1e3;
|
|
32984
|
+
const requeued = s < segments;
|
|
32985
|
+
const nextSession = `session-${id}-s${s}`;
|
|
32986
|
+
emit2("step.checkpointed", id, {
|
|
32987
|
+
segment: s,
|
|
32988
|
+
segmentsMax: segments,
|
|
32989
|
+
headSha: `local${s}`,
|
|
32990
|
+
elapsedSeconds: elapsedS,
|
|
32991
|
+
remainingSeconds: Math.max(0, jobWallS - elapsedS),
|
|
32992
|
+
requeued,
|
|
32993
|
+
...requeued ? {
|
|
32994
|
+
nextSegment: s + 1
|
|
32995
|
+
} : {},
|
|
32996
|
+
...sessionRef ? {
|
|
32997
|
+
resumedFrom: sessionRef
|
|
32998
|
+
} : {},
|
|
32999
|
+
sessionRef: nextSession,
|
|
33000
|
+
reason: requeued ? "segment_boundary" : "interval"
|
|
33001
|
+
});
|
|
33002
|
+
say(`[${stamp()}] ${id} \xB7 checkpointed \xB7 segment ${s}/${segments}${requeued ? ` \u2192 re-queued (resume ${nextSession})` : ""}`);
|
|
33003
|
+
sessionRef = nextSession;
|
|
33004
|
+
}
|
|
33005
|
+
return {
|
|
33006
|
+
text: `[fake:${single.id}] ${segments} segment(s) over ${jobWallS} s \u2014 ${prompt.slice(0, 40)}`,
|
|
33007
|
+
...fakeObject(single)
|
|
33008
|
+
};
|
|
33009
|
+
}
|
|
33010
|
+
return {
|
|
33011
|
+
text: `[fake:${single.id}] ${prompt.slice(0, 80)}`,
|
|
33012
|
+
...fakeObject(single)
|
|
33013
|
+
};
|
|
33014
|
+
}, "agentReply");
|
|
33015
|
+
const fakeObject = /* @__PURE__ */ __name((single) => single.outputSchema ? {
|
|
33016
|
+
object: stubFromSchema(single.outputSchema)
|
|
33017
|
+
} : {}, "fakeObject");
|
|
32303
33018
|
const executeSingle = /* @__PURE__ */ __name(async (row2, single, input) => {
|
|
32304
33019
|
const id = row2.stepId;
|
|
32305
33020
|
const drift = stepInputIssue(single, input);
|
|
@@ -32344,57 +33059,12 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
32344
33059
|
}
|
|
32345
33060
|
}
|
|
32346
33061
|
case "agent": {
|
|
32347
|
-
const
|
|
32348
|
-
|
|
32349
|
-
|
|
32350
|
-
|
|
32351
|
-
if (!opts.agentInvoke) throw new StepFailure("AGENTS_LIVE_UNAVAILABLE", "--agents live needs a dev API session");
|
|
32352
|
-
const t0 = Date.now();
|
|
32353
|
-
const out = await withWall(id, single, () => opts.agentInvoke(single, prompt, input));
|
|
32354
|
-
record(id, row2.attempt, {
|
|
32355
|
-
prompt,
|
|
32356
|
-
input
|
|
32357
|
-
}, out, Date.now() - t0);
|
|
32358
|
-
return out;
|
|
32359
|
-
}
|
|
32360
|
-
if (single.tier === "job" && jobWallS !== void 0) {
|
|
32361
|
-
const segments = Math.max(1, Math.ceil(jobWallS / WORKFLOW_LOCAL_JOB_SEGMENT_MAX_S));
|
|
32362
|
-
let sessionRef;
|
|
32363
|
-
let elapsedS = 0;
|
|
32364
|
-
for (let s = 1; s <= segments; s++) {
|
|
32365
|
-
const wallS = Math.min(WORKFLOW_LOCAL_JOB_SEGMENT_MAX_S, jobWallS - elapsedS);
|
|
32366
|
-
elapsedS += wallS;
|
|
32367
|
-
clock += wallS * 1e3;
|
|
32368
|
-
const requeued = s < segments;
|
|
32369
|
-
const nextSession = `session-${id}-s${s}`;
|
|
32370
|
-
emit2("step.checkpointed", id, {
|
|
32371
|
-
segment: s,
|
|
32372
|
-
segmentsMax: segments,
|
|
32373
|
-
headSha: `local${s}`,
|
|
32374
|
-
elapsedSeconds: elapsedS,
|
|
32375
|
-
remainingSeconds: Math.max(0, jobWallS - elapsedS),
|
|
32376
|
-
requeued,
|
|
32377
|
-
...requeued ? {
|
|
32378
|
-
nextSegment: s + 1
|
|
32379
|
-
} : {},
|
|
32380
|
-
...sessionRef ? {
|
|
32381
|
-
resumedFrom: sessionRef
|
|
32382
|
-
} : {},
|
|
32383
|
-
sessionRef: nextSession,
|
|
32384
|
-
reason: requeued ? "segment_boundary" : "interval"
|
|
32385
|
-
});
|
|
32386
|
-
say(`[${stamp()}] ${id} \xB7 checkpointed \xB7 segment ${s}/${segments}${requeued ? ` \u2192 re-queued (resume ${nextSession})` : ""}`);
|
|
32387
|
-
sessionRef = nextSession;
|
|
32388
|
-
}
|
|
32389
|
-
return {
|
|
32390
|
-
text: `[fake:${single.id}] ${segments} segment(s) over ${jobWallS} s \u2014 ${prompt.slice(0, 40)}`,
|
|
32391
|
-
object: stubFromSchema(single.outputSchema)
|
|
32392
|
-
};
|
|
33062
|
+
const reply = await agentReply(row2, single, input);
|
|
33063
|
+
const coerced = coerceAgentStepOutput(single.outputSchema, reply);
|
|
33064
|
+
if (!coerced.ok) {
|
|
33065
|
+
throw new StepFailure("OUTPUT_SCHEMA_INVALID", `agent reply is not the declared outputSchema object \u2014 ${coerced.reason}`);
|
|
32393
33066
|
}
|
|
32394
|
-
return
|
|
32395
|
-
text: `[fake:${single.id}] ${prompt.slice(0, 80)}`,
|
|
32396
|
-
object: stubFromSchema(single.outputSchema)
|
|
32397
|
-
};
|
|
33067
|
+
return coerced.output;
|
|
32398
33068
|
}
|
|
32399
33069
|
case "tool": {
|
|
32400
33070
|
if (opts.fixturesDir) return readFixture(id, row2.attempt);
|
|
@@ -32649,33 +33319,35 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
32649
33319
|
if (armRow && !taken.includes(a)) skipRow(armRow, "branch_not_taken");
|
|
32650
33320
|
}
|
|
32651
33321
|
}, "runBranch");
|
|
33322
|
+
const aliasJoin = /* @__PURE__ */ __name((containerId, containerRow, output2) => {
|
|
33323
|
+
stepResults[containerId] = output2;
|
|
33324
|
+
if (containerRow?.node.kind === "foreach") {
|
|
33325
|
+
stepResults[armId2(containerRow.node.entry.step)] = output2;
|
|
33326
|
+
}
|
|
33327
|
+
}, "aliasJoin");
|
|
32652
33328
|
const runJoin = /* @__PURE__ */ __name((row2) => {
|
|
32653
33329
|
const container = row2.node.container ?? row2.stepId.replace(/\.join$/, "");
|
|
32654
33330
|
const containerRow = rows3.get(container);
|
|
32655
33331
|
const children = row2.dependsOn.filter((d) => d !== container);
|
|
32656
33332
|
const completed = children.filter((c) => rows3.get(c)?.status === "completed");
|
|
33333
|
+
let output2;
|
|
32657
33334
|
if (containerRow?.node.kind === "branch") {
|
|
32658
|
-
|
|
33335
|
+
output2 = completed.length === 1 ? stepResults[completed[0]] : Object.fromEntries(completed.map((c) => [
|
|
32659
33336
|
c,
|
|
32660
33337
|
stepResults[c]
|
|
32661
33338
|
]));
|
|
32662
|
-
|
|
32663
|
-
|
|
32664
|
-
|
|
32665
|
-
|
|
32666
|
-
}
|
|
32667
|
-
if (containerRow?.node.kind === "foreach") {
|
|
32668
|
-
terminalize(row2, "completed", {
|
|
32669
|
-
output: children.map((c) => stepResults[c])
|
|
32670
|
-
});
|
|
32671
|
-
return;
|
|
32672
|
-
}
|
|
32673
|
-
terminalize(row2, "completed", {
|
|
32674
|
-
output: Object.fromEntries(completed.map((c) => [
|
|
33339
|
+
} else if (containerRow?.node.kind === "foreach") {
|
|
33340
|
+
output2 = children.map((c) => stepResults[c]);
|
|
33341
|
+
} else {
|
|
33342
|
+
output2 = Object.fromEntries(completed.map((c) => [
|
|
32675
33343
|
c,
|
|
32676
33344
|
stepResults[c]
|
|
32677
|
-
]))
|
|
33345
|
+
]));
|
|
33346
|
+
}
|
|
33347
|
+
terminalize(row2, "completed", {
|
|
33348
|
+
output: output2
|
|
32678
33349
|
});
|
|
33350
|
+
aliasJoin(container, containerRow, output2);
|
|
32679
33351
|
}, "runJoin");
|
|
32680
33352
|
const runForeach = /* @__PURE__ */ __name(async (row2, entry) => {
|
|
32681
33353
|
const items = inputFor(row2);
|
|
@@ -32818,19 +33490,28 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
32818
33490
|
say(`[${stamp()}] ${row2.stepId} \xB7 approval \xB7 "${entry.title ?? row2.stepId}" \u2014 awaiting decision`);
|
|
32819
33491
|
answer = await opts.prompt("approval", row2.stepId, entry);
|
|
32820
33492
|
}
|
|
33493
|
+
const decidedBy = {
|
|
33494
|
+
id: opts.userId ?? "local",
|
|
33495
|
+
kind: "user"
|
|
33496
|
+
};
|
|
32821
33497
|
if (answer.decision === "deny") {
|
|
32822
|
-
const
|
|
33498
|
+
const resumeData2 = {
|
|
32823
33499
|
approved: false,
|
|
32824
|
-
|
|
33500
|
+
...answer.reason ? {
|
|
33501
|
+
note: answer.reason
|
|
33502
|
+
} : {},
|
|
33503
|
+
editRevision: 0,
|
|
33504
|
+
decidedBy
|
|
32825
33505
|
};
|
|
32826
|
-
|
|
33506
|
+
const output2 = workflowApprovalOutput(resumeData2);
|
|
33507
|
+
if ((entry.onDeny ?? "continue") !== "fail") {
|
|
32827
33508
|
terminalize(row2, "completed", {
|
|
32828
33509
|
output: output2
|
|
32829
33510
|
});
|
|
32830
33511
|
return;
|
|
32831
33512
|
}
|
|
32832
33513
|
row2.error = {
|
|
32833
|
-
code: "
|
|
33514
|
+
code: "approval_denied",
|
|
32834
33515
|
message: answer.reason ?? "denied"
|
|
32835
33516
|
};
|
|
32836
33517
|
terminalize(row2, "failed", {
|
|
@@ -32842,13 +33523,27 @@ async function runWorkflowLocallyInner(rawOpts) {
|
|
|
32842
33523
|
};
|
|
32843
33524
|
return;
|
|
32844
33525
|
}
|
|
32845
|
-
const
|
|
32846
|
-
|
|
32847
|
-
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
|
|
33526
|
+
const edited = answer.payload !== void 0;
|
|
33527
|
+
if (edited) {
|
|
33528
|
+
const shown = inputFor(row2);
|
|
33529
|
+
const editable = entry.editablePaths ?? [];
|
|
33530
|
+
if (editable.length) {
|
|
33531
|
+
const bad = changedPointers(shown, answer.payload).filter((p) => !matchesEditablePath(p, editable));
|
|
33532
|
+
if (bad.length) {
|
|
33533
|
+
throw new WorkflowLocalUsageError("edit-path-not-allowed", `--approve ${row2.stepId}: path "${pointerToDotPath(bad[0])}" changed outside editablePaths [${editable.join(", ")}] (the payload the approval showed: ${JSON.stringify(shown)})`, row2.stepId);
|
|
33534
|
+
}
|
|
32851
33535
|
}
|
|
33536
|
+
}
|
|
33537
|
+
const resumeData = {
|
|
33538
|
+
approved: true,
|
|
33539
|
+
...edited ? {
|
|
33540
|
+
editedPayload: answer.payload
|
|
33541
|
+
} : {},
|
|
33542
|
+
editRevision: edited ? 1 : 0,
|
|
33543
|
+
decidedBy
|
|
33544
|
+
};
|
|
33545
|
+
terminalize(row2, "completed", {
|
|
33546
|
+
output: workflowApprovalOutput(resumeData)
|
|
32852
33547
|
});
|
|
32853
33548
|
}, "runApproval");
|
|
32854
33549
|
const runSignal = /* @__PURE__ */ __name(async (row2, entry) => {
|
|
@@ -33323,7 +34018,16 @@ function createSandbox(options) {
|
|
|
33323
34018
|
},
|
|
33324
34019
|
// Legacy `env('FOO')` getter — kept for backwards compatibility with skills
|
|
33325
34020
|
// that use it instead of `process.env.FOO`. Both work.
|
|
33326
|
-
|
|
34021
|
+
// LUA-751: `env.template(KEY)` too — a graph-form workflow file calls it at MODULE scope (`schedule.timezone:
|
|
34022
|
+
// env.template('FINANCE_TZ')`, the shipped `vendor-invoices`), `env` is not one of the builder names esbuild
|
|
34023
|
+
// injects (`WORKFLOW_SHIM_NAMES`), so the artifact resolves it against THIS global when `lua workflows run`
|
|
34024
|
+
// loads it — and threw `env.template is not a function`. The placeholder is the SDK's (`types/skill.ts`) and the
|
|
34025
|
+
// compiler's tier-1 stub's (`graph-serializer.ts`); the local `--env` overlay substitutes it on the graph.
|
|
34026
|
+
env: Object.assign((key) => envVars[key], {
|
|
34027
|
+
template: /* @__PURE__ */ __name((key) => ({
|
|
34028
|
+
__envRef: key
|
|
34029
|
+
}), "template")
|
|
34030
|
+
}),
|
|
33327
34031
|
BasketStatus,
|
|
33328
34032
|
OrderStatus,
|
|
33329
34033
|
AI: {
|
|
@@ -33850,9 +34554,23 @@ var WorkflowHandler = class extends BaseVersionedHandler {
|
|
|
33850
34554
|
});
|
|
33851
34555
|
return {
|
|
33852
34556
|
success: response.success,
|
|
33853
|
-
error: response.error?.message
|
|
34557
|
+
error: response.error?.message,
|
|
34558
|
+
statusCode: response.error?.statusCode,
|
|
34559
|
+
code: response.error?.code ?? response.error?.error
|
|
33854
34560
|
};
|
|
33855
34561
|
}
|
|
34562
|
+
/**
|
|
34563
|
+
* LUA-750: R1 (`getWorkflows`) lists EVERY non-deleted workflow of the agent, active or not, so a yaml
|
|
34564
|
+
* `workflowId` absent from it is a definition `lua workflows delete` soft-deleted. Only rows in local code (the
|
|
34565
|
+
* manifest) are re-registered; a server-only stub with a dead id is left for the user.
|
|
34566
|
+
*/
|
|
34567
|
+
staleYamlRows(yamlItems, serverItems, manifestNames) {
|
|
34568
|
+
const serverIds = new Set(serverItems.map((s) => s?.id));
|
|
34569
|
+
return yamlItems.filter((row2) => {
|
|
34570
|
+
const id = this.getItemId(row2);
|
|
34571
|
+
return !!id && !serverIds.has(id) && manifestNames.has(row2.name);
|
|
34572
|
+
});
|
|
34573
|
+
}
|
|
33856
34574
|
async publishVersion(apiKey, agentId, entityId, version) {
|
|
33857
34575
|
const api = this.getApi(apiKey, agentId);
|
|
33858
34576
|
const response = await api.publishWorkflowVersion(entityId, version);
|
|
@@ -34022,9 +34740,10 @@ var syncableHandlers = Object.values(primitiveHandlers);
|
|
|
34022
34740
|
|
|
34023
34741
|
// src/commands/compile.ts
|
|
34024
34742
|
init_analytics();
|
|
34743
|
+
init_cli_error();
|
|
34025
34744
|
async function compileCommand(options) {
|
|
34026
34745
|
return withErrorHandling(async () => {
|
|
34027
|
-
const debugMode = options?.debug ||
|
|
34746
|
+
const debugMode = options?.debug || debugEnabled();
|
|
34028
34747
|
const verboseMode = options?.verbose || debugMode;
|
|
34029
34748
|
const doSync = options?.sync === true;
|
|
34030
34749
|
const doServerSync = options?.serverSync !== false;
|
|
@@ -34095,7 +34814,7 @@ async function compileCommand(options) {
|
|
|
34095
34814
|
when: "error"
|
|
34096
34815
|
});
|
|
34097
34816
|
}
|
|
34098
|
-
throw new
|
|
34817
|
+
throw new CliError("compile_failed", "Compilation failed \u2014 see errors above.");
|
|
34099
34818
|
}
|
|
34100
34819
|
ensureGitignored(rootDir, "dist-v2/", "dist/");
|
|
34101
34820
|
if (result.warnings.length > 0) {
|
|
@@ -34263,6 +34982,7 @@ function suggestClosest(input, candidates) {
|
|
|
34263
34982
|
__name(suggestClosest, "suggestClosest");
|
|
34264
34983
|
|
|
34265
34984
|
// src/utils/aliases.ts
|
|
34985
|
+
init_cli_error();
|
|
34266
34986
|
function lowerKeys(aliases) {
|
|
34267
34987
|
const out = {};
|
|
34268
34988
|
for (const k of Object.keys(aliases)) {
|
|
@@ -34687,6 +35407,8 @@ var ALIAS_MAP = {
|
|
|
34687
35407
|
"list",
|
|
34688
35408
|
"get",
|
|
34689
35409
|
"create",
|
|
35410
|
+
"edit",
|
|
35411
|
+
"raise",
|
|
34690
35412
|
"pause",
|
|
34691
35413
|
"resume",
|
|
34692
35414
|
"close"
|
|
@@ -34699,6 +35421,12 @@ var ALIAS_MAP = {
|
|
|
34699
35421
|
new: "create",
|
|
34700
35422
|
add: "create",
|
|
34701
35423
|
set: "create",
|
|
35424
|
+
// LUA-749: `edit` (R63) / `raise` (R64)
|
|
35425
|
+
update: "edit",
|
|
35426
|
+
patch: "edit",
|
|
35427
|
+
change: "edit",
|
|
35428
|
+
bump: "raise",
|
|
35429
|
+
increase: "raise",
|
|
34702
35430
|
hold: "pause",
|
|
34703
35431
|
stop: "pause",
|
|
34704
35432
|
unpause: "resume",
|
|
@@ -35068,11 +35796,9 @@ function validateOrSuggest(group, input, opts) {
|
|
|
35068
35796
|
}
|
|
35069
35797
|
const suggestion = suggestClosest(normalized ?? input, candidates);
|
|
35070
35798
|
if (suggestion) {
|
|
35071
|
-
throw
|
|
35072
|
-
Valid values: ${candidates.join(", ")}`);
|
|
35799
|
+
throw CliError.usage(`lua: "${input}" is not a valid ${group} value. Did you mean "${suggestion}"?`, `Valid values: ${candidates.join(", ")}`);
|
|
35073
35800
|
}
|
|
35074
|
-
throw
|
|
35075
|
-
Valid values: ${candidates.join(", ")}`);
|
|
35801
|
+
throw CliError.usage(`lua: "${input}" is not a valid ${group} value.`, `Valid values: ${candidates.join(", ")}`);
|
|
35076
35802
|
}
|
|
35077
35803
|
__name(validateOrSuggest, "validateOrSuggest");
|
|
35078
35804
|
|
|
@@ -35080,6 +35806,27 @@ __name(validateOrSuggest, "validateOrSuggest");
|
|
|
35080
35806
|
import fs17 from "fs";
|
|
35081
35807
|
import path23 from "path";
|
|
35082
35808
|
init_cli();
|
|
35809
|
+
|
|
35810
|
+
// src/utils/stdout-redirect.ts
|
|
35811
|
+
async function withStdoutToStderr(active, fn) {
|
|
35812
|
+
if (!active) return fn();
|
|
35813
|
+
const originalWrite = process.stdout.write;
|
|
35814
|
+
const originalLog = console.log;
|
|
35815
|
+
const originalInfo = console.info;
|
|
35816
|
+
process.stdout.write = (chunk, ...rest) => process.stderr.write(chunk, ...rest);
|
|
35817
|
+
console.log = (...args2) => console.error(...args2);
|
|
35818
|
+
console.info = (...args2) => console.error(...args2);
|
|
35819
|
+
try {
|
|
35820
|
+
return await fn();
|
|
35821
|
+
} finally {
|
|
35822
|
+
process.stdout.write = originalWrite;
|
|
35823
|
+
console.log = originalLog;
|
|
35824
|
+
console.info = originalInfo;
|
|
35825
|
+
}
|
|
35826
|
+
}
|
|
35827
|
+
__name(withStdoutToStderr, "withStdoutToStderr");
|
|
35828
|
+
|
|
35829
|
+
// src/commands/workflow-local-run.ts
|
|
35083
35830
|
init_command_utils();
|
|
35084
35831
|
init_artifact_loader();
|
|
35085
35832
|
init_types();
|
|
@@ -35094,6 +35841,7 @@ __name(runIdOf, "runIdOf");
|
|
|
35094
35841
|
init_dist2();
|
|
35095
35842
|
|
|
35096
35843
|
// src/utils/workflow-script-local.ts
|
|
35844
|
+
init_dist();
|
|
35097
35845
|
function fakeCompletionFor(intent) {
|
|
35098
35846
|
const env = intent.argsEnvelope ?? {};
|
|
35099
35847
|
switch (intent.kind) {
|
|
@@ -35115,10 +35863,14 @@ function fakeCompletionFor(intent) {
|
|
|
35115
35863
|
case "approval":
|
|
35116
35864
|
return {
|
|
35117
35865
|
status: "completed",
|
|
35118
|
-
output: {
|
|
35866
|
+
output: workflowApprovalOutput({
|
|
35119
35867
|
approved: true,
|
|
35120
|
-
|
|
35121
|
-
|
|
35868
|
+
editRevision: 0,
|
|
35869
|
+
decidedBy: {
|
|
35870
|
+
id: "local",
|
|
35871
|
+
kind: "user"
|
|
35872
|
+
}
|
|
35873
|
+
})
|
|
35122
35874
|
};
|
|
35123
35875
|
case "waitForSignal":
|
|
35124
35876
|
case "signal":
|
|
@@ -35269,8 +36021,426 @@ async function runScriptWorkflowLocally(opts, runner) {
|
|
|
35269
36021
|
__name(runScriptWorkflowLocally, "runScriptWorkflowLocally");
|
|
35270
36022
|
|
|
35271
36023
|
// src/utils/workflow-script-replay.ts
|
|
36024
|
+
init_dist4();
|
|
35272
36025
|
import { createRequire as createRequire2 } from "module";
|
|
35273
36026
|
import vm5 from "vm";
|
|
36027
|
+
import { createHash as createHash7, randomUUID as randomUUID4 } from "crypto";
|
|
36028
|
+
|
|
36029
|
+
// ../sandbox-runtime/dist/workflow-script-wrapper.mjs
|
|
36030
|
+
var __defProp7 = Object.defineProperty;
|
|
36031
|
+
var __name7 = /* @__PURE__ */ __name((target, value3) => __defProp7(target, "name", { value: value3, configurable: true }), "__name");
|
|
36032
|
+
var WORKFLOW_SCRIPT_RUNTIME_KEY = "__luaWorkflowScriptRuntime";
|
|
36033
|
+
var WORKFLOW_SCRIPT_PROTOCOL_VERSION = 1;
|
|
36034
|
+
var WORKFLOW_SCRIPT_DEFAULT_CAPS = {
|
|
36035
|
+
maxOutstanding: 64,
|
|
36036
|
+
maxEffects: 1e3,
|
|
36037
|
+
maxForeachItems: 4096,
|
|
36038
|
+
scriptWallMs: 3e4,
|
|
36039
|
+
argsMaxBytes: 32 * 1024,
|
|
36040
|
+
stepOutputMaxBytes: 256 * 1024,
|
|
36041
|
+
stepsPerTick: 64,
|
|
36042
|
+
logCap: 1e3,
|
|
36043
|
+
phaseCap: 64,
|
|
36044
|
+
envCap: 4096
|
|
36045
|
+
};
|
|
36046
|
+
var WORKFLOW_SCRIPT_REPLAY_SOURCE = String.raw`
|
|
36047
|
+
(function __luaWorkflowScriptReplay(__rt, __input, __bodyFactory) {
|
|
36048
|
+
'use strict';
|
|
36049
|
+
var setImmediateReal = __rt.setImmediate, nowReal = __rt.now, randomReal = __rt.random, uuidReal = __rt.uuid, sha256Hex = __rt.sha256Hex;
|
|
36050
|
+
var caps = __input.caps || {};
|
|
36051
|
+
var MAX_OUTSTANDING = caps.maxOutstanding || 64;
|
|
36052
|
+
var MAX_EFFECTS = caps.maxEffects || 1000;
|
|
36053
|
+
var MAX_FOREACH = caps.maxForeachItems || 4096;
|
|
36054
|
+
var ARGS_MAX = caps.argsMaxBytes || 32768;
|
|
36055
|
+
var STEP_OUT_MAX = caps.stepOutputMaxBytes || 262144;
|
|
36056
|
+
var STEPS_PER_TICK = caps.stepsPerTick || 64;
|
|
36057
|
+
var LOG_CAP = caps.logCap || 1000, PHASE_CAP = caps.phaseCap || 64, ENV_CAP = caps.envCap || 4096;
|
|
36058
|
+
var INLINE_KINDS = { memo: 1, env: 1, log: 1, phase: 1, budget: 1 };
|
|
36059
|
+
var pendingCount = typeof __input.pendingCount === 'number' ? __input.pendingCount : 0;
|
|
36060
|
+
|
|
36061
|
+
// --- canonicalJson + callHash (04 §4.3.4) — byte-identical to lua-core's reference ---
|
|
36062
|
+
function canonicalJson(v) {
|
|
36063
|
+
if (v === null || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'string') return JSON.stringify(v);
|
|
36064
|
+
if (Array.isArray(v)) { var parts = []; for (var i = 0; i < v.length; i++) parts.push(v[i] === undefined ? 'null' : canonicalJson(v[i])); return '[' + parts.join(',') + ']'; }
|
|
36065
|
+
if (typeof v === 'object') {
|
|
36066
|
+
var keys = Object.keys(v).filter(function (k) { return v[k] !== undefined; }).sort();
|
|
36067
|
+
return '{' + keys.map(function (k) { return JSON.stringify(k) + ':' + canonicalJson(v[k]); }).join(',') + '}';
|
|
36068
|
+
}
|
|
36069
|
+
return 'null';
|
|
36070
|
+
}
|
|
36071
|
+
function callHash(kind, argsForHash) { return 'sha256-cj1:' + sha256Hex(kind + '\n' + canonicalJson(argsForHash)); }
|
|
36072
|
+
function byteSize(v) { try { return JSON.stringify(v === undefined ? null : v).length; } catch (e) { return Infinity; } }
|
|
36073
|
+
function typedError(code, message, extra) { var e = new Error(message || code); e.code = code; if (extra) Object.assign(e, extra); return e; }
|
|
36074
|
+
function errShape(e) {
|
|
36075
|
+
if (e && typeof e === 'object') return { code: String(e.code || 'SCRIPT_THREW'), message: String(e.message || e).slice(0, 1024) };
|
|
36076
|
+
return { code: 'SCRIPT_THREW', message: String(e).slice(0, 1024) };
|
|
36077
|
+
}
|
|
36078
|
+
|
|
36079
|
+
// --- state (04 §4.3.5) ---
|
|
36080
|
+
var journalBySeq = {};
|
|
36081
|
+
var journal = Array.isArray(__input.journal) ? __input.journal : [];
|
|
36082
|
+
for (var j = 0; j < journal.length; j++) journalBySeq[journal[j].seq] = journal[j];
|
|
36083
|
+
var nextSeq = 0, cancelling = false, divergence = null, bailed = null;
|
|
36084
|
+
var issuedCount = 0, intents = [], pending = {};
|
|
36085
|
+
var stepCount = 0, logCount = 0, phaseCount = 0, envCount = 0, currentPhase = undefined;
|
|
36086
|
+
var narration = [];
|
|
36087
|
+
var inClosure = false;
|
|
36088
|
+
|
|
36089
|
+
function drain() { return new Promise(function (r) { setImmediateReal(r); }); }
|
|
36090
|
+
function never() { return new Promise(function () {}); }
|
|
36091
|
+
function deferred() { var d = {}; d.promise = new Promise(function (res, rej) { d.resolve = res; d.reject = rej; }); d.promise.catch(function () {}); return d; }
|
|
36092
|
+
function abort(d) { if (!divergence) divergence = d; }
|
|
36093
|
+
|
|
36094
|
+
// §4.3.5 issue(call): sync return for inline kinds, a promise for async kinds.
|
|
36095
|
+
function issue(call) {
|
|
36096
|
+
if (inClosure) throw typedError('SCRIPT_STEP_THREW', 'host call inside step()');
|
|
36097
|
+
if (divergence) { if (call.settle === 'inline') throw typedError('JOURNAL_DIVERGENCE', 'aborted'); return never(); }
|
|
36098
|
+
var seq = nextSeq;
|
|
36099
|
+
var entry = journalBySeq[seq];
|
|
36100
|
+
if (!entry && cancelling) throw typedError('RUN_CANCELLED', 'RUN_CANCELLED: the run is cancelling; no new intents may be issued');
|
|
36101
|
+
if (!entry && seq >= MAX_EFFECTS) { abort({ reason: 'effect_cap', seq: seq }); throw typedError('EFFECT_CAP_EXCEEDED', 'EFFECT_CAP_EXCEEDED: more than ' + MAX_EFFECTS + ' effects in one run'); }
|
|
36102
|
+
if (call.argsEnvelope !== undefined && byteSize(call.argsEnvelope) > ARGS_MAX) throw typedError('ARGS_TOO_LARGE', 'ARGS_TOO_LARGE: argsEnvelope over ' + ARGS_MAX + ' bytes');
|
|
36103
|
+
nextSeq++;
|
|
36104
|
+
issuedCount++;
|
|
36105
|
+
var hash = callHash(call.kind, call.argsForHash);
|
|
36106
|
+
if (entry) {
|
|
36107
|
+
if (entry.callHash !== hash) {
|
|
36108
|
+
abort({ reason: 'hash_mismatch', seq: seq, expected: entry.callHash, got: hash });
|
|
36109
|
+
if (call.settle === 'inline') throw typedError('JOURNAL_DIVERGENCE', 'hash mismatch at seq ' + seq);
|
|
36110
|
+
return never();
|
|
36111
|
+
}
|
|
36112
|
+
if (entry.settle === 'inline') {
|
|
36113
|
+
if (call.settlesAsPromise) { var d0 = deferred(); if (entry.status === 'failed' || entry.error) d0.reject(typedError((entry.error && entry.error.code) || 'MEMO_THREW', entry.error && entry.error.message)); else d0.resolve(entry.output); return d0.promise; }
|
|
36114
|
+
if (entry.error) throw typedError(entry.error.code, entry.error.message);
|
|
36115
|
+
return entry.output;
|
|
36116
|
+
}
|
|
36117
|
+
if (entry.status === 'pending') return never();
|
|
36118
|
+
var d = deferred(); pending[seq] = { d: d, kind: call.kind }; return d.promise;
|
|
36119
|
+
}
|
|
36120
|
+
// Fresh call — no journal row.
|
|
36121
|
+
if (call.settle === 'inline') {
|
|
36122
|
+
if (call.computeAsync) {
|
|
36123
|
+
var d1 = deferred();
|
|
36124
|
+
var started = nowReal();
|
|
36125
|
+
// memo/step(): host members are throwing stubs for the closure's
|
|
36126
|
+
// synchronous extent (05 §5.7.4 "effects are issued by the script,
|
|
36127
|
+
// never by a step"); the awaited tail cannot reach a timer or fetch.
|
|
36128
|
+
Promise.resolve().then(function () { if (call.closure) inClosure = true; try { return call.computeAsync(); } finally { inClosure = false; } }).then(function (out) {
|
|
36129
|
+
var rec = { seq: seq, kind: call.kind, settle: 'inline', callHash: hash, argsEnvelope: call.argsEnvelope, status: 'completed', output: out === undefined ? null : out, durationMs: nowReal() - started };
|
|
36130
|
+
if (call.narration) rec.narration = call.narration;
|
|
36131
|
+
if (byteSize(out) > STEP_OUT_MAX) { rec.status = 'failed'; delete rec.output; rec.error = { code: 'OUTPUT_TOO_LARGE', message: 'inline result over ' + STEP_OUT_MAX + ' bytes' }; intents.push(rec); d1.reject(typedError('OUTPUT_TOO_LARGE', rec.error.message)); return; }
|
|
36132
|
+
intents.push(rec); d1.resolve(out);
|
|
36133
|
+
}, function (err) {
|
|
36134
|
+
var es = errShape(err); es = call.kind === 'code' ? { code: 'SCRIPT_STEP_THREW', message: es.message } : { code: 'MEMO_THREW', message: es.message };
|
|
36135
|
+
var rec = { seq: seq, kind: call.kind, settle: 'inline', callHash: hash, argsEnvelope: call.argsEnvelope, status: 'failed', error: es, durationMs: nowReal() - started };
|
|
36136
|
+
if (call.narration) rec.narration = call.narration;
|
|
36137
|
+
intents.push(rec); d1.reject(typedError(es.code, es.message));
|
|
36138
|
+
});
|
|
36139
|
+
return d1.promise;
|
|
36140
|
+
}
|
|
36141
|
+
var output = call.compute ? call.compute() : undefined;
|
|
36142
|
+
var rec2 = { seq: seq, kind: call.kind, settle: 'inline', callHash: hash, argsEnvelope: call.argsEnvelope, status: 'completed', output: output === undefined ? null : output };
|
|
36143
|
+
if (call.narration) rec2.narration = call.narration;
|
|
36144
|
+
intents.push(rec2);
|
|
36145
|
+
return output;
|
|
36146
|
+
}
|
|
36147
|
+
var asyncRec = { seq: seq, kind: call.kind, settle: 'async', callHash: hash, argsEnvelope: call.argsEnvelope };
|
|
36148
|
+
if (call.narration) asyncRec.narration = call.narration;
|
|
36149
|
+
if (call.role !== undefined) asyncRec.role = call.role;
|
|
36150
|
+
if (call.model !== undefined) asyncRec.model = call.model;
|
|
36151
|
+
intents.push(asyncRec);
|
|
36152
|
+
var outstanding = 0; for (var q = 0; q < intents.length; q++) if (intents[q].settle === 'async') outstanding++;
|
|
36153
|
+
if (outstanding > MAX_OUTSTANDING) {
|
|
36154
|
+
// Thrown to the script with NO seq consumed (deterministic: the same
|
|
36155
|
+
// prefix always trips at the same call) — the over-cap intent is never proposed.
|
|
36156
|
+
intents.pop(); nextSeq--; issuedCount--;
|
|
36157
|
+
throw typedError('OUTSTANDING_INTENTS_EXCEEDED', 'OUTSTANDING_INTENTS_EXCEEDED: more than ' + MAX_OUTSTANDING + ' unsettled intents in one tick');
|
|
36158
|
+
}
|
|
36159
|
+
return never();
|
|
36160
|
+
}
|
|
36161
|
+
|
|
36162
|
+
function narr(opts) { var n = {}; if (opts && opts.label) n.label = String(opts.label); var ph = (opts && opts.phase) || currentPhase; if (ph) n.phase = String(ph); return (n.label || n.phase) ? n : undefined; }
|
|
36163
|
+
function resolveModel(opts) {
|
|
36164
|
+
if (opts && opts.model) return opts.model;
|
|
36165
|
+
var ph = (opts && opts.phase) || currentPhase; var phases = __input.meta && __input.meta.phases;
|
|
36166
|
+
if (ph && Array.isArray(phases)) for (var i = 0; i < phases.length; i++) if (phases[i] && phases[i].title === ph && phases[i].model) return phases[i].model;
|
|
36167
|
+
return undefined;
|
|
36168
|
+
}
|
|
36169
|
+
function resolveRole(role) {
|
|
36170
|
+
if (role === undefined) return undefined;
|
|
36171
|
+
if (role && typeof role === 'object' && typeof role.ref === 'string') {
|
|
36172
|
+
var keys = Object.keys(role); if (keys.length > 1) throw typedError('EPHEMERAL_ROLE_INVALID', 'role ref mixed with inline keys', { reason: 'ref_and_inline' });
|
|
36173
|
+
var b = __input.roleBindings && __input.roleBindings[role.ref];
|
|
36174
|
+
if (!b) throw typedError('EPHEMERAL_ROLE_INVALID', 'unknown role ref ' + role.ref, { reason: 'ref_unknown' });
|
|
36175
|
+
return b;
|
|
36176
|
+
}
|
|
36177
|
+
if (role && typeof role === 'object') {
|
|
36178
|
+
if (typeof role.instructions === 'string' && role.instructions.length > 4000) throw typedError('EPHEMERAL_ROLE_INVALID', 'role.instructions over 4000 chars', { reason: 'too_long' });
|
|
36179
|
+
if (Array.isArray(role.tools) && role.tools.length > 64) throw typedError('EPHEMERAL_ROLE_INVALID', 'role.tools over 64', { reason: 'too_many_tools' });
|
|
36180
|
+
}
|
|
36181
|
+
return role;
|
|
36182
|
+
}
|
|
36183
|
+
function checkItems(items) { if (!Array.isArray(items)) throw new TypeError('expected an array'); if (items.length > MAX_FOREACH) throw typedError('TOO_MANY_ITEMS', 'foreach_too_many_items', { itemCount: items.length, cap: MAX_FOREACH }); }
|
|
36184
|
+
function thunkOrNull(fn) { try { return Promise.resolve(fn()).catch(function () { return null; }); } catch (e) { return Promise.resolve(null); } }
|
|
36185
|
+
|
|
36186
|
+
var host = {
|
|
36187
|
+
args: __input.args,
|
|
36188
|
+
agent: function (prompt, opts) {
|
|
36189
|
+
var o = opts || {};
|
|
36190
|
+
var role = resolveRole(o.role);
|
|
36191
|
+
if (role !== undefined && o.agentId !== undefined && o.agentId !== '$self') throw typedError('EPHEMERAL_ROLE_INVALID', 'a role step must run on the owner', { reason: 'base_not_self' });
|
|
36192
|
+
var model = resolveModel(o);
|
|
36193
|
+
var afh = { prompt: prompt, agentId: o.agentId, schema: o.schema, model: model, toolScope: o.toolScope, timeoutSeconds: o.timeoutSeconds, data: o.data };
|
|
36194
|
+
if ('role' in o) afh.role = role;
|
|
36195
|
+
var env = { prompt: prompt }; for (var k in o) if (k !== 'role') env[k] = o[k]; if ('role' in o) env.role = role; if (model !== undefined) env.model = model;
|
|
36196
|
+
return issue({ kind: 'agent', settle: 'async', argsForHash: afh, argsEnvelope: env, narration: narr(o), role: ('role' in o) ? role : undefined, model: model });
|
|
36197
|
+
},
|
|
36198
|
+
tool: function (toolId, input, opts) { var o = opts || {}; var env = { toolId: toolId, input: input }; for (var k in o) env[k] = o[k]; return issue({ kind: 'tool', settle: 'async', argsForHash: { toolId: toolId, input: input, timeoutSeconds: o.timeoutSeconds }, argsEnvelope: env, narration: narr(o) }); },
|
|
36199
|
+
shell: function (command, opts) { var o = opts || {}; var env = { command: command }; for (var k in o) env[k] = o[k]; return issue({ kind: 'code', settle: 'async', argsForHash: { command: command, timeoutSeconds: o.timeoutSeconds, workspace: o.workspace, jobResources: o.jobResources }, argsEnvelope: env, narration: narr(o) }); },
|
|
36200
|
+
merge: function (opts) { var o = opts || {}; return issue({ kind: 'merge', settle: 'async', argsForHash: { strategy: o.strategy, onConflict: o.onConflict, arms: o.arms }, argsEnvelope: o, narration: narr(o) }); },
|
|
36201
|
+
workflow: function (nameOrGraph, input, opts) {
|
|
36202
|
+
var o = opts || {};
|
|
36203
|
+
var ref = typeof nameOrGraph === 'string' ? nameOrGraph : 'sha256-cj1:' + sha256Hex(canonicalJson(nameOrGraph && nameOrGraph.definition !== undefined ? { definition: nameOrGraph.definition } : nameOrGraph));
|
|
36204
|
+
return issue({ kind: 'workflow', settle: 'async', argsForHash: { ref: ref, input: input }, argsEnvelope: { workflow: nameOrGraph, input: input, label: o.label, phase: o.phase }, narration: narr(o) });
|
|
36205
|
+
},
|
|
36206
|
+
sleep: function (ms, opts) { var env = { ms: ms }; if (opts && opts.businessHours) env.businessHours = opts.businessHours; return issue({ kind: 'sleep', settle: 'async', argsForHash: { ms: ms }, argsEnvelope: env }); },
|
|
36207
|
+
sleepUntil: function (iso, opts) { var env = { iso: iso }; if (opts) for (var k in opts) env[k] = opts[k]; return issue({ kind: 'sleepUntil', settle: 'async', argsForHash: { iso: iso }, argsEnvelope: env }); },
|
|
36208
|
+
approval: function (req) { var r = req || {}; return issue({ kind: 'approval', settle: 'async', argsForHash: { title: r.title, details: r.details, approver: r.approver, timeoutHours: r.timeoutHours, editable: r.editable }, argsEnvelope: r, narration: narr(r) }); },
|
|
36209
|
+
waitForSignal: function (name, opts) { var o = opts || {}; var env = { name: name }; for (var k in o) env[k] = o[k]; return issue({ kind: 'signal', settle: 'async', argsForHash: { name: name, timeoutHours: o.timeoutHours, acceptedSources: o.acceptedSources }, argsEnvelope: env, narration: narr(o) }); },
|
|
36210
|
+
step: function (label, fn, opts) {
|
|
36211
|
+
var o = opts || {};
|
|
36212
|
+
if (o.timeoutSeconds !== undefined && !(o.timeoutSeconds >= 1 && o.timeoutSeconds <= 600)) throw typedError('SCRIPT_META_INVALID', 'step timeoutSeconds outside 1..600', { reason: 'step-timeout-invalid' });
|
|
36213
|
+
if (cancelling && journalBySeq[nextSeq] === undefined) throw typedError('RUN_CANCELLED', 'RUN_CANCELLED');
|
|
36214
|
+
if (journalBySeq[nextSeq] === undefined) { if (stepCount >= STEPS_PER_TICK) throw typedError('script-step-too-many', 'more than ' + STEPS_PER_TICK + ' step() closures in one tick'); stepCount++; }
|
|
36215
|
+
return issue({ kind: 'code', settle: 'inline', settlesAsPromise: true, closure: true, argsForHash: { label: label, fn: String(fn) }, argsEnvelope: { label: label, timeoutSeconds: o.timeoutSeconds }, computeAsync: fn, narration: { label: String(label) } });
|
|
36216
|
+
},
|
|
36217
|
+
memo: function (key, fn) { return issue({ kind: 'memo', settle: 'inline', settlesAsPromise: true, closure: true, argsForHash: { key: key }, argsEnvelope: { key: key }, computeAsync: fn }); },
|
|
36218
|
+
now: function () { if (envCount++ >= ENV_CAP && journalBySeq[nextSeq] === undefined) throw typedError('ENV_CAP_EXCEEDED', 'ENV_CAP_EXCEEDED'); return issue({ kind: 'env', settle: 'inline', argsForHash: { fn: 'now' }, argsEnvelope: { fn: 'now' }, compute: nowReal }); },
|
|
36219
|
+
random: function () { if (envCount++ >= ENV_CAP && journalBySeq[nextSeq] === undefined) throw typedError('ENV_CAP_EXCEEDED', 'ENV_CAP_EXCEEDED'); return issue({ kind: 'env', settle: 'inline', argsForHash: { fn: 'random' }, argsEnvelope: { fn: 'random' }, compute: randomReal }); },
|
|
36220
|
+
uuid: function () { if (envCount++ >= ENV_CAP && journalBySeq[nextSeq] === undefined) throw typedError('ENV_CAP_EXCEEDED', 'ENV_CAP_EXCEEDED'); return issue({ kind: 'env', settle: 'inline', argsForHash: { fn: 'uuid' }, argsEnvelope: { fn: 'uuid' }, compute: uuidReal }); },
|
|
36221
|
+
log: function (message) {
|
|
36222
|
+
var m = String(message).slice(0, 1024);
|
|
36223
|
+
if (logCount >= LOG_CAP) { if (logCount === LOG_CAP) narration.push({ kind: 'log', message: 'LOG_CAP' }); logCount++; return; }
|
|
36224
|
+
logCount++; narration.push({ kind: 'log', message: m });
|
|
36225
|
+
issue({ kind: 'log', settle: 'inline', argsForHash: { message: m }, argsEnvelope: { message: m }, compute: function () { return undefined; } });
|
|
36226
|
+
},
|
|
36227
|
+
phase: function (title) {
|
|
36228
|
+
var t = String(title);
|
|
36229
|
+
if (phaseCount >= PHASE_CAP) { if (phaseCount === PHASE_CAP) narration.push({ kind: 'phase', message: 'PHASE_CAP' }); phaseCount++; return; }
|
|
36230
|
+
phaseCount++; currentPhase = t; narration.push({ kind: 'phase', title: t });
|
|
36231
|
+
issue({ kind: 'phase', settle: 'inline', argsForHash: { title: t }, argsEnvelope: { title: t }, compute: function () { return undefined; } });
|
|
36232
|
+
},
|
|
36233
|
+
parallel: function (thunks) { checkItems(thunks); var ps = []; for (var i = 0; i < thunks.length; i++) ps.push(thunkOrNull(thunks[i])); return Promise.all(ps); },
|
|
36234
|
+
pipeline: function (items) {
|
|
36235
|
+
checkItems(items); var stages = Array.prototype.slice.call(arguments, 1);
|
|
36236
|
+
return Promise.all(items.map(function (item, i) { var p = Promise.resolve(undefined); stages.forEach(function (st) { p = p.then(function (prev) { return st(prev, item, i); }); }); return p; }));
|
|
36237
|
+
},
|
|
36238
|
+
foreach: function (items, opts, fn) {
|
|
36239
|
+
if (typeof opts === 'function') { fn = opts; opts = {}; }
|
|
36240
|
+
checkItems(items); var o = opts || {};
|
|
36241
|
+
var conc = Math.max(1, Math.min(32, o.concurrency || 8)); var results = new Array(items.length); var next = 0;
|
|
36242
|
+
function worker() { if (next >= items.length) return Promise.resolve(); var i = next++; return Promise.resolve().then(function () { return fn(items[i], i); }).then(function (v) { results[i] = v; }, function () { results[i] = null; }).then(worker); }
|
|
36243
|
+
var ws = []; for (var w = 0; w < Math.min(conc, items.length); w++) ws.push(worker());
|
|
36244
|
+
return Promise.all(ws).then(function () { return results; });
|
|
36245
|
+
},
|
|
36246
|
+
bailRun: function (output) { if (byteSize(output) > 262144) throw typedError('OUTPUT_TOO_LARGE', 'bailRun output over 256 KB'); bailed = { output: output === undefined ? null : output, seq: nextSeq }; throw typedError('__LUA_BAIL_RUN__', 'bailRun'); },
|
|
36247
|
+
artefacts: {
|
|
36248
|
+
put: function (name, data, opts) { var o = opts || {}; var digest = typeof data === 'string' ? sha256Hex(data) : sha256Hex(String(data)); return issue({ kind: 'artefact', settle: 'async', argsForHash: { op: 'put', name: name, sha256: digest, contentType: o.contentType, kind: o.kind, title: o.title, source: o.source }, argsEnvelope: { op: 'put', name: name, sha256: digest, contentType: o.contentType, kind: o.kind, title: o.title, source: o.source, bytes: typeof data === 'string' ? data.length : undefined } }); },
|
|
36249
|
+
get: function (artefactId) { return issue({ kind: 'artefact', settle: 'async', argsForHash: { op: 'get', artefactId: artefactId }, argsEnvelope: { op: 'get', artefactId: artefactId } }); },
|
|
36250
|
+
list: function () { return issue({ kind: 'artefact', settle: 'async', argsForHash: { op: 'list' }, argsEnvelope: { op: 'list' } }); },
|
|
36251
|
+
},
|
|
36252
|
+
};
|
|
36253
|
+
|
|
36254
|
+
// 04 §4.3.5 null-vs-reject table.
|
|
36255
|
+
function settle(p, entry) {
|
|
36256
|
+
if (entry.status === 'cancelled') { cancelling = true; p.d.resolve(null); return; }
|
|
36257
|
+
if (entry.status === 'completed') { p.d.resolve(p.kind === 'sleep' || p.kind === 'sleepUntil' ? undefined : entry.output); return; }
|
|
36258
|
+
switch (p.kind) {
|
|
36259
|
+
case 'agent': case 'tool': case 'code': case 'merge': p.d.resolve(null); return;
|
|
36260
|
+
case 'sleep': case 'sleepUntil': p.d.resolve(undefined); return;
|
|
36261
|
+
case 'approval': case 'signal': p.d.resolve(entry.output === undefined ? null : entry.output); return;
|
|
36262
|
+
default: p.d.reject(typedError((entry.error && entry.error.code) || 'UNKNOWN', (entry.error && entry.error.message) || 'journaled failure'));
|
|
36263
|
+
}
|
|
36264
|
+
}
|
|
36265
|
+
|
|
36266
|
+
var body = { settled: false, resolved: false, value: undefined, error: null };
|
|
36267
|
+
return (async function () {
|
|
36268
|
+
var bodyPromise;
|
|
36269
|
+
try { bodyPromise = Promise.resolve().then(function () { return __bodyFactory(host)(); }); }
|
|
36270
|
+
catch (e) { bodyPromise = Promise.reject(e); }
|
|
36271
|
+
bodyPromise.then(function (v) { body.settled = true; body.resolved = true; body.value = v; }, function (e) { body.settled = true; body.resolved = false; body.error = e; });
|
|
36272
|
+
// round 0
|
|
36273
|
+
await drain();
|
|
36274
|
+
// rounds 1..N in completionSeq order (inline entries never participate)
|
|
36275
|
+
var applied = journal.filter(function (e) { return e.settle === 'async' && e.status !== 'pending'; })
|
|
36276
|
+
.sort(function (a, b) { return (a.completionSeq == null ? Number.MAX_SAFE_INTEGER : a.completionSeq) - (b.completionSeq == null ? Number.MAX_SAFE_INTEGER : b.completionSeq); });
|
|
36277
|
+
for (var i = 0; i < applied.length; i++) {
|
|
36278
|
+
if (divergence || bailed) break;
|
|
36279
|
+
var entry = applied[i];
|
|
36280
|
+
if (entry.seq >= nextSeq) { abort({ reason: 'entry_before_issue', seq: entry.seq }); break; }
|
|
36281
|
+
var p = pending[entry.seq];
|
|
36282
|
+
if (p) { delete pending[entry.seq]; settle(p, entry); }
|
|
36283
|
+
await drain();
|
|
36284
|
+
}
|
|
36285
|
+
if (!divergence && !bailed) for (var k = 0; k < journal.length; k++) if (journal[k].settle === 'async' && journal[k].seq >= nextSeq) { abort({ reason: 'journal_longer_than_script', seq: journal[k].seq }); break; }
|
|
36286
|
+
var base = { __lua_workflow: 'script', intents: intents, issued: issuedCount, narration: narration };
|
|
36287
|
+
if (divergence) {
|
|
36288
|
+
if (divergence.reason === 'effect_cap') return Object.assign(base, { outcome: 'failed', error: { code: 'EFFECT_CAP_EXCEEDED', message: 'EFFECT_CAP_EXCEEDED at seq ' + divergence.seq } });
|
|
36289
|
+
return Object.assign(base, { outcome: 'failed', error: { code: 'JOURNAL_DIVERGENCE', message: 'JOURNAL_DIVERGENCE(' + divergence.reason + ') at seq ' + divergence.seq, divergence: divergence } });
|
|
36290
|
+
}
|
|
36291
|
+
if (bailed) return Object.assign(base, { outcome: 'bailed', output: bailed.output, bailSeq: bailed.seq });
|
|
36292
|
+
if (body.settled) {
|
|
36293
|
+
if (body.resolved) { if (byteSize(body.value) > 262144) return Object.assign(base, { outcome: 'failed', error: { code: 'OUTPUT_TOO_LARGE', message: 'script return value over 256 KB' } }); return Object.assign(base, { outcome: 'done', output: body.value === undefined ? null : body.value }); }
|
|
36294
|
+
var es = errShape(body.error); if (es.code === '__LUA_BAIL_RUN__' && bailed) return Object.assign(base, { outcome: 'bailed', output: bailed.output, bailSeq: bailed.seq });
|
|
36295
|
+
return Object.assign(base, { outcome: 'failed', error: { code: es.code === 'SCRIPT_THREW' || !es.code ? 'SCRIPT_THREW' : es.code, message: es.message } });
|
|
36296
|
+
}
|
|
36297
|
+
var asyncIntents = intents.filter(function (it) { return it.settle === 'async'; });
|
|
36298
|
+
if (asyncIntents.length === 0 && pendingCount === 0 && !journal.some(function (e) { return e.settle === 'async' && e.status === 'pending'; })) {
|
|
36299
|
+
return Object.assign(base, { outcome: 'failed', error: { code: 'ORCHESTRATION_DEADLOCK', message: 'script parked with no intents and no pending effects' } });
|
|
36300
|
+
}
|
|
36301
|
+
return Object.assign(base, { outcome: 'parked', phaseTree: narration.filter(function (n) { return n.kind === 'phase'; }), stateSnapshot: undefined });
|
|
36302
|
+
})();
|
|
36303
|
+
})`;
|
|
36304
|
+
var WORKFLOW_SCRIPT_REPLAY_SOURCES = Object.freeze({
|
|
36305
|
+
[WORKFLOW_SCRIPT_PROTOCOL_VERSION]: WORKFLOW_SCRIPT_REPLAY_SOURCE
|
|
36306
|
+
});
|
|
36307
|
+
var WORKFLOW_SCRIPT_PROTOCOL_VERSIONS = Object.freeze(Object.keys(WORKFLOW_SCRIPT_REPLAY_SOURCES).map(Number).filter((v) => v <= WORKFLOW_SCRIPT_PROTOCOL_VERSION && v >= WORKFLOW_SCRIPT_PROTOCOL_VERSION - 2).sort((a, b) => b - a));
|
|
36308
|
+
var WORKFLOW_SCRIPT_PROTOCOL_INTRODUCED_AT = Object.freeze({
|
|
36309
|
+
1: "2026-08-30"
|
|
36310
|
+
});
|
|
36311
|
+
function computeWorkflowProtocolShipWindow(input) {
|
|
36312
|
+
const { current } = input;
|
|
36313
|
+
const held = [
|
|
36314
|
+
...new Set(input.held)
|
|
36315
|
+
].filter((v) => v <= current).sort((a, b) => b - a);
|
|
36316
|
+
const prev = held.includes(current - 1) ? current - 1 : void 0;
|
|
36317
|
+
const prev2 = held.includes(current - 2) ? current - 2 : void 0;
|
|
36318
|
+
const introduced = Date.parse(input.introducedAt[current] ?? "");
|
|
36319
|
+
const now = input.now ?? Date.now();
|
|
36320
|
+
const ageMs = Number.isFinite(introduced) ? Math.max(0, now - introduced) : 0;
|
|
36321
|
+
if (prev === void 0) {
|
|
36322
|
+
return {
|
|
36323
|
+
versions: [
|
|
36324
|
+
current
|
|
36325
|
+
],
|
|
36326
|
+
dropped: held.filter((v) => v !== current),
|
|
36327
|
+
state: "single",
|
|
36328
|
+
ageMs
|
|
36329
|
+
};
|
|
36330
|
+
}
|
|
36331
|
+
const elapsed = Number.isFinite(introduced) && ageMs >= input.drainDays * 864e5;
|
|
36332
|
+
if (elapsed && input.stragglers === 0) {
|
|
36333
|
+
return {
|
|
36334
|
+
versions: [
|
|
36335
|
+
current
|
|
36336
|
+
],
|
|
36337
|
+
dropped: held.filter((v) => v !== current),
|
|
36338
|
+
state: "drained",
|
|
36339
|
+
ageMs
|
|
36340
|
+
};
|
|
36341
|
+
}
|
|
36342
|
+
const versions = [
|
|
36343
|
+
current,
|
|
36344
|
+
prev,
|
|
36345
|
+
...prev2 !== void 0 ? [
|
|
36346
|
+
prev2
|
|
36347
|
+
] : []
|
|
36348
|
+
];
|
|
36349
|
+
return {
|
|
36350
|
+
versions,
|
|
36351
|
+
dropped: held.filter((v) => !versions.includes(v)),
|
|
36352
|
+
state: elapsed ? "blocked" : "draining",
|
|
36353
|
+
ageMs
|
|
36354
|
+
};
|
|
36355
|
+
}
|
|
36356
|
+
__name(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
36357
|
+
__name7(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
36358
|
+
function workflowScriptReplaySource(journalProtocolVersion) {
|
|
36359
|
+
return WORKFLOW_SCRIPT_PROTOCOL_VERSIONS.includes(journalProtocolVersion) ? WORKFLOW_SCRIPT_REPLAY_SOURCES[journalProtocolVersion] : void 0;
|
|
36360
|
+
}
|
|
36361
|
+
__name(workflowScriptReplaySource, "workflowScriptReplaySource");
|
|
36362
|
+
__name7(workflowScriptReplaySource, "workflowScriptReplaySource");
|
|
36363
|
+
var HOST_BINDINGS = [
|
|
36364
|
+
"args",
|
|
36365
|
+
"agent",
|
|
36366
|
+
"tool",
|
|
36367
|
+
"shell",
|
|
36368
|
+
"merge",
|
|
36369
|
+
"workflow",
|
|
36370
|
+
"sleep",
|
|
36371
|
+
"sleepUntil",
|
|
36372
|
+
"approval",
|
|
36373
|
+
"waitForSignal",
|
|
36374
|
+
"step",
|
|
36375
|
+
"memo",
|
|
36376
|
+
"now",
|
|
36377
|
+
"random",
|
|
36378
|
+
"uuid",
|
|
36379
|
+
"log",
|
|
36380
|
+
"phase",
|
|
36381
|
+
"parallel",
|
|
36382
|
+
"pipeline",
|
|
36383
|
+
"foreach",
|
|
36384
|
+
"bailRun",
|
|
36385
|
+
"artefacts"
|
|
36386
|
+
];
|
|
36387
|
+
function transformWorkflowScriptModule(script) {
|
|
36388
|
+
return script.replace(/^\s*export\s+const\s+meta\s*=/m, "const meta =");
|
|
36389
|
+
}
|
|
36390
|
+
__name(transformWorkflowScriptModule, "transformWorkflowScriptModule");
|
|
36391
|
+
__name7(transformWorkflowScriptModule, "transformWorkflowScriptModule");
|
|
36392
|
+
function buildWorkflowScriptWrapper(script, input) {
|
|
36393
|
+
const tick = input ?? {};
|
|
36394
|
+
const version = tick.journalProtocolVersion ?? WORKFLOW_SCRIPT_PROTOCOL_VERSION;
|
|
36395
|
+
const replaySource = workflowScriptReplaySource(version);
|
|
36396
|
+
if (replaySource === void 0) {
|
|
36397
|
+
return {
|
|
36398
|
+
code: `
|
|
36399
|
+
{
|
|
36400
|
+
const __platformErr = new Error('[Lua] workflow-script journalProtocolVersion ${JSON.stringify(version)} is outside this runner window ${JSON.stringify(WORKFLOW_SCRIPT_PROTOCOL_VERSIONS)}');
|
|
36401
|
+
__platformErr.code = 'runtime_incompatible';
|
|
36402
|
+
throw __platformErr;
|
|
36403
|
+
}
|
|
36404
|
+
`,
|
|
36405
|
+
contextName: "WorkflowScriptExecutionContext",
|
|
36406
|
+
contextOrigin: "workflow-script-execution",
|
|
36407
|
+
source: "workflow-script",
|
|
36408
|
+
timeoutMs: 6e5
|
|
36409
|
+
};
|
|
36410
|
+
}
|
|
36411
|
+
const bindings = HOST_BINDINGS.map((k) => `${k} = __host.${k}`).join(", ");
|
|
36412
|
+
const code = `
|
|
36413
|
+
const __luaWfRt = globalThis[${JSON.stringify(WORKFLOW_SCRIPT_RUNTIME_KEY)}];
|
|
36414
|
+
delete globalThis[${JSON.stringify(WORKFLOW_SCRIPT_RUNTIME_KEY)}];
|
|
36415
|
+
if (!__luaWfRt || typeof __luaWfRt.setImmediate !== 'function' || typeof __luaWfRt.sha256Hex !== 'function') {
|
|
36416
|
+
const __platformErr = new Error('[Lua] workflow-script runtime handle missing \u2014 the site was dispatched outside the workflows queue set');
|
|
36417
|
+
__platformErr.code = 'PLATFORM_VM_ERROR';
|
|
36418
|
+
throw __platformErr;
|
|
36419
|
+
}
|
|
36420
|
+
const __luaWfInput = ${JSON.stringify(input ?? null)};
|
|
36421
|
+
const __luaWfReplay = ${replaySource};
|
|
36422
|
+
__luaWfReplay(__luaWfRt, __luaWfInput, function (__host) {
|
|
36423
|
+
const ${bindings};
|
|
36424
|
+
return async function __luaWorkflowScriptBody() {
|
|
36425
|
+
${transformWorkflowScriptModule(script)}
|
|
36426
|
+
};
|
|
36427
|
+
});
|
|
36428
|
+
`;
|
|
36429
|
+
return {
|
|
36430
|
+
code,
|
|
36431
|
+
contextName: "WorkflowScriptExecutionContext",
|
|
36432
|
+
contextOrigin: "workflow-script-execution",
|
|
36433
|
+
source: "workflow-script",
|
|
36434
|
+
// The tick wall is the sum of orchestration (LUA_WF_SCRIPT_WALL_MS, 30 s)
|
|
36435
|
+
// and step() closure walls; the process hard wall stays the site's
|
|
36436
|
+
// LUA_SANDBOX_MAX_EXECUTION_MS (05 §5.7.4 clock 3) — envelope wallMs overrides.
|
|
36437
|
+
timeoutMs: 6e5
|
|
36438
|
+
};
|
|
36439
|
+
}
|
|
36440
|
+
__name(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
|
|
36441
|
+
__name7(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
|
|
36442
|
+
|
|
36443
|
+
// src/utils/workflow-script-replay.ts
|
|
35274
36444
|
var ReplayRuntimeUnavailableError = class extends Error {
|
|
35275
36445
|
static {
|
|
35276
36446
|
__name(this, "ReplayRuntimeUnavailableError");
|
|
@@ -35337,7 +36507,59 @@ function compareScriptReplay(bundle, result) {
|
|
|
35337
36507
|
};
|
|
35338
36508
|
}
|
|
35339
36509
|
__name(compareScriptReplay, "compareScriptReplay");
|
|
35340
|
-
|
|
36510
|
+
var QUIET_CONSOLE = {
|
|
36511
|
+
log() {
|
|
36512
|
+
},
|
|
36513
|
+
info() {
|
|
36514
|
+
},
|
|
36515
|
+
warn() {
|
|
36516
|
+
},
|
|
36517
|
+
error() {
|
|
36518
|
+
},
|
|
36519
|
+
debug() {
|
|
36520
|
+
}
|
|
36521
|
+
};
|
|
36522
|
+
function runWrapper(code, sandbox, tick, filename) {
|
|
36523
|
+
const context = vm5.createContext(sandbox);
|
|
36524
|
+
const value3 = vm5.runInContext(code, context, {
|
|
36525
|
+
filename,
|
|
36526
|
+
timeout: Math.max(1e3, tick.caps?.scriptWallMs ?? 3e4)
|
|
36527
|
+
});
|
|
36528
|
+
return Promise.resolve(value3);
|
|
36529
|
+
}
|
|
36530
|
+
__name(runWrapper, "runWrapper");
|
|
36531
|
+
function localScriptRuntimeHandle() {
|
|
36532
|
+
const realSetImmediate = setImmediate;
|
|
36533
|
+
const RealDate = Date;
|
|
36534
|
+
const realRandom = Math.random;
|
|
36535
|
+
return {
|
|
36536
|
+
setImmediate: /* @__PURE__ */ __name((cb) => realSetImmediate(cb), "setImmediate"),
|
|
36537
|
+
now: /* @__PURE__ */ __name(() => RealDate.now(), "now"),
|
|
36538
|
+
random: /* @__PURE__ */ __name(() => realRandom(), "random"),
|
|
36539
|
+
uuid: /* @__PURE__ */ __name(() => randomUUID4(), "uuid"),
|
|
36540
|
+
sha256Hex: /* @__PURE__ */ __name((text) => createHash7("sha256").update(text).digest("hex"), "sha256Hex")
|
|
36541
|
+
};
|
|
36542
|
+
}
|
|
36543
|
+
__name(localScriptRuntimeHandle, "localScriptRuntimeHandle");
|
|
36544
|
+
function bundledScriptRunner() {
|
|
36545
|
+
const runner = /* @__PURE__ */ __name(async (tick) => {
|
|
36546
|
+
const sandbox = createBaseSandboxContext({
|
|
36547
|
+
envVars: {},
|
|
36548
|
+
customConsole: QUIET_CONSOLE,
|
|
36549
|
+
extraGlobals: {
|
|
36550
|
+
...buildWorkflowScriptGlobals(QUIET_CONSOLE),
|
|
36551
|
+
[WORKFLOW_SCRIPT_RUNTIME_KEY]: localScriptRuntimeHandle()
|
|
36552
|
+
}
|
|
36553
|
+
});
|
|
36554
|
+
const wrapper = buildWorkflowScriptWrapper(tick.script, tick);
|
|
36555
|
+
return runWrapper(wrapper.code, sandbox, tick, "workflow-script-local.js");
|
|
36556
|
+
}, "runner");
|
|
36557
|
+
return Object.assign(runner, {
|
|
36558
|
+
runtime: "bundled"
|
|
36559
|
+
});
|
|
36560
|
+
}
|
|
36561
|
+
__name(bundledScriptRunner, "bundledScriptRunner");
|
|
36562
|
+
function projectScriptRunner(projectDir) {
|
|
35341
36563
|
let runtime;
|
|
35342
36564
|
try {
|
|
35343
36565
|
const req = createRequire2(`${projectDir.replace(/\/$/, "")}/package.json`);
|
|
@@ -35348,35 +36570,37 @@ function loadLocalScriptRunner(projectDir = process.cwd()) {
|
|
|
35348
36570
|
if (typeof runtime?.createSandboxContext !== "function" || typeof runtime?.buildWorkflowScriptWrapper !== "function") {
|
|
35349
36571
|
throw new ReplayRuntimeUnavailableError("runtime exports missing");
|
|
35350
36572
|
}
|
|
35351
|
-
|
|
35352
|
-
const quiet = {
|
|
35353
|
-
log() {
|
|
35354
|
-
},
|
|
35355
|
-
info() {
|
|
35356
|
-
},
|
|
35357
|
-
warn() {
|
|
35358
|
-
},
|
|
35359
|
-
error() {
|
|
35360
|
-
},
|
|
35361
|
-
debug() {
|
|
35362
|
-
}
|
|
35363
|
-
};
|
|
36573
|
+
const runner = /* @__PURE__ */ __name(async (tick) => {
|
|
35364
36574
|
const sandbox = runtime.createSandboxContext({
|
|
35365
36575
|
siteType: "workflow-script"
|
|
35366
|
-
}, void 0, void 0,
|
|
36576
|
+
}, void 0, void 0, QUIET_CONSOLE, void 0, {});
|
|
35367
36577
|
const wrapper = runtime.buildWorkflowScriptWrapper(tick.script, tick);
|
|
35368
|
-
|
|
35369
|
-
|
|
35370
|
-
|
|
35371
|
-
|
|
35372
|
-
|
|
35373
|
-
|
|
35374
|
-
|
|
36578
|
+
return runWrapper(wrapper.code, sandbox, tick, "workflow-script-replay.js");
|
|
36579
|
+
}, "runner");
|
|
36580
|
+
return Object.assign(runner, {
|
|
36581
|
+
runtime: "project"
|
|
36582
|
+
});
|
|
36583
|
+
}
|
|
36584
|
+
__name(projectScriptRunner, "projectScriptRunner");
|
|
36585
|
+
function loadLocalScriptRunner(projectDir = process.cwd(), opts = {}) {
|
|
36586
|
+
const mode = opts.runtime ?? "auto";
|
|
36587
|
+
if (mode === "bundled") return bundledScriptRunner();
|
|
36588
|
+
try {
|
|
36589
|
+
return projectScriptRunner(projectDir);
|
|
36590
|
+
} catch (e) {
|
|
36591
|
+
if (mode === "project" || !(e instanceof ReplayRuntimeUnavailableError)) throw e;
|
|
36592
|
+
return bundledScriptRunner();
|
|
36593
|
+
}
|
|
35375
36594
|
}
|
|
35376
36595
|
__name(loadLocalScriptRunner, "loadLocalScriptRunner");
|
|
35377
36596
|
async function replayScriptRunLocally(bundle, runner = loadLocalScriptRunner()) {
|
|
35378
36597
|
const result = await runner(bundle.tick);
|
|
35379
|
-
|
|
36598
|
+
const report = compareScriptReplay(bundle, result);
|
|
36599
|
+
const runtime = runner.runtime;
|
|
36600
|
+
return runtime ? {
|
|
36601
|
+
...report,
|
|
36602
|
+
runtime
|
|
36603
|
+
} : report;
|
|
35380
36604
|
}
|
|
35381
36605
|
__name(replayScriptRunLocally, "replayScriptRunLocally");
|
|
35382
36606
|
function formatScriptReplayReport(r) {
|
|
@@ -35385,6 +36609,9 @@ function formatScriptReplayReport(r) {
|
|
|
35385
36609
|
lines.push(`j${row2.seq} \xB7 ${row2.kind} \xB7 recorded=${row2.recordedHash.slice(0, 20)}\u2026 \xB7 local=${(row2.localHash ?? "-").slice(0, 20)}\u2026${row2.diverged ? ` \xB7 DIVERGED (${row2.reason})` : ""}`);
|
|
35386
36610
|
}
|
|
35387
36611
|
lines.push(`local outcome: ${r.localOutcome}${r.localError ? ` (${r.localError.code}: ${r.localError.message})` : ""} \xB7 server status: ${r.serverStatus} \xB7 new intents: ${r.newIntents}`);
|
|
36612
|
+
if (r.runtime) {
|
|
36613
|
+
lines.push(`wrapper: ${r.runtime === "project" ? "the project's @lua/sandbox-runtime" : "bundled with this lua-cli"} (LUA-751)`);
|
|
36614
|
+
}
|
|
35388
36615
|
return lines;
|
|
35389
36616
|
}
|
|
35390
36617
|
__name(formatScriptReplayReport, "formatScriptReplayReport");
|
|
@@ -35529,15 +36756,15 @@ async function runWorkflowLocalFromProject(name, flags) {
|
|
|
35529
36756
|
}, "say");
|
|
35530
36757
|
if (!flags.noCompile) {
|
|
35531
36758
|
say("\u{1F4E6} Compiling code first...");
|
|
35532
|
-
await compileCommand({
|
|
36759
|
+
await withStdoutToStderr(asJson, () => compileCommand({
|
|
35533
36760
|
serverSync: false
|
|
35534
|
-
});
|
|
36761
|
+
}));
|
|
35535
36762
|
}
|
|
35536
36763
|
const manifest = loadManifest();
|
|
35537
36764
|
const workflows = getPrimitivesByKind(manifest, PrimitiveKind.WORKFLOW);
|
|
35538
36765
|
if (workflows.length === 0) {
|
|
35539
36766
|
console.error("\u274C No workflows found in compiled output.");
|
|
35540
|
-
console.log("\u{1F4A1} Create a workflow with createWorkflow(...).commit() in your code.");
|
|
36767
|
+
(asJson ? console.error : console.log)("\u{1F4A1} Create a workflow with createWorkflow(...).commit() in your code.");
|
|
35541
36768
|
return {
|
|
35542
36769
|
exitCode: 3
|
|
35543
36770
|
};
|
|
@@ -36640,6 +37867,72 @@ init_command_utils();
|
|
|
36640
37867
|
init_semver();
|
|
36641
37868
|
init_auth_error();
|
|
36642
37869
|
init_constants();
|
|
37870
|
+
|
|
37871
|
+
// src/api/agent-version.api.service.ts
|
|
37872
|
+
init_http_client();
|
|
37873
|
+
var AgentVersionApi = class extends HttpClient {
|
|
37874
|
+
static {
|
|
37875
|
+
__name(this, "AgentVersionApi");
|
|
37876
|
+
}
|
|
37877
|
+
agentId;
|
|
37878
|
+
constructor(baseUrl, credential, agentId) {
|
|
37879
|
+
super(baseUrl, credential);
|
|
37880
|
+
this.agentId = agentId;
|
|
37881
|
+
}
|
|
37882
|
+
get basePath() {
|
|
37883
|
+
return `/developer/agents/${encodeURIComponent(this.agentId)}`;
|
|
37884
|
+
}
|
|
37885
|
+
get authHeader() {
|
|
37886
|
+
return {};
|
|
37887
|
+
}
|
|
37888
|
+
// ---------------------------------------------------------------------------
|
|
37889
|
+
// Version CRUD
|
|
37890
|
+
// ---------------------------------------------------------------------------
|
|
37891
|
+
async createVersion(body) {
|
|
37892
|
+
return this.httpPost(`${this.basePath}/versions`, body, this.authHeader);
|
|
37893
|
+
}
|
|
37894
|
+
async listVersions(query) {
|
|
37895
|
+
const params = new URLSearchParams();
|
|
37896
|
+
if (query?.all !== void 0) params.append("all", String(query.all));
|
|
37897
|
+
if (query?.limit !== void 0) params.append("limit", String(query.limit));
|
|
37898
|
+
if (query?.status !== void 0) params.append("status", query.status);
|
|
37899
|
+
const qs = params.toString();
|
|
37900
|
+
const url = qs ? `${this.basePath}/versions?${qs}` : `${this.basePath}/versions`;
|
|
37901
|
+
return this.httpGet(url, this.authHeader);
|
|
37902
|
+
}
|
|
37903
|
+
async getVersion(version) {
|
|
37904
|
+
return this.httpGet(`${this.basePath}/versions/${version}`, this.authHeader);
|
|
37905
|
+
}
|
|
37906
|
+
async deleteVersion(version) {
|
|
37907
|
+
return this.httpDelete(`${this.basePath}/versions/${version}`, this.authHeader);
|
|
37908
|
+
}
|
|
37909
|
+
// ---------------------------------------------------------------------------
|
|
37910
|
+
// Diff
|
|
37911
|
+
// ---------------------------------------------------------------------------
|
|
37912
|
+
async diffVersions(from, to) {
|
|
37913
|
+
const url = `${this.basePath}/versions/diff?from=${from}&to=${to}`;
|
|
37914
|
+
return this.httpGet(url, this.authHeader);
|
|
37915
|
+
}
|
|
37916
|
+
// ---------------------------------------------------------------------------
|
|
37917
|
+
// Promote
|
|
37918
|
+
// ---------------------------------------------------------------------------
|
|
37919
|
+
async promoteVersion(version) {
|
|
37920
|
+
return this.httpPost(`${this.basePath}/versions/${version}/promote`, {}, this.authHeader);
|
|
37921
|
+
}
|
|
37922
|
+
// ---------------------------------------------------------------------------
|
|
37923
|
+
// Patch commit hash — called by `lua version create` after a successful git
|
|
37924
|
+
// commit + tag to propagate the SHA to the backend AgentVersion record.
|
|
37925
|
+
// Failure is non-fatal; the version snapshot is valid whether or not this
|
|
37926
|
+
// PATCH lands.
|
|
37927
|
+
// ---------------------------------------------------------------------------
|
|
37928
|
+
async patchCommitHash(version, commitHash) {
|
|
37929
|
+
return this.httpPatch(`${this.basePath}/versions/${version}/commit-hash`, {
|
|
37930
|
+
commitHash
|
|
37931
|
+
}, this.authHeader);
|
|
37932
|
+
}
|
|
37933
|
+
};
|
|
37934
|
+
|
|
37935
|
+
// src/commands/push.ts
|
|
36643
37936
|
init_artifact_loader();
|
|
36644
37937
|
init_bundle_upload();
|
|
36645
37938
|
init_types();
|
|
@@ -37479,6 +38772,7 @@ var GIT_MESSAGES = {
|
|
|
37479
38772
|
var tagName = /* @__PURE__ */ __name((version) => `lua/v${version}`, "tagName");
|
|
37480
38773
|
|
|
37481
38774
|
// src/commands/push-helpers.ts
|
|
38775
|
+
init_cli_error();
|
|
37482
38776
|
function pickPushAllNextStepVariant(opts) {
|
|
37483
38777
|
if (opts.pushedSomething && opts.failedCount === 0) return "success";
|
|
37484
38778
|
if (opts.pushedSomething && opts.failedCount > 0) return "partial";
|
|
@@ -37501,6 +38795,15 @@ function formatPushFailureSummary(failedItems) {
|
|
|
37501
38795
|
return lines.join("\n");
|
|
37502
38796
|
}
|
|
37503
38797
|
__name(formatPushFailureSummary, "formatPushFailureSummary");
|
|
38798
|
+
function stalePushEntryError(handler, name, entityId, serverMessage) {
|
|
38799
|
+
const field = handler.yamlConfig.idField;
|
|
38800
|
+
return new CliError("not_found", `${handler.displayName} "${name}" (${entityId}) no longer exists on the server${serverMessage ? ` \u2014 ${serverMessage}` : ""}`, {
|
|
38801
|
+
exitCode: CLI_EXIT.NOT_FOUND,
|
|
38802
|
+
statusCode: 404,
|
|
38803
|
+
hint: `lua.skill.yaml still holds ${field}: ${entityId} for "${name}". Run \`lua compile\` \u2014 the server sync clears a deleted id and registers the definition afresh \u2014 then push again; or remove the ${field} line by hand.`
|
|
38804
|
+
});
|
|
38805
|
+
}
|
|
38806
|
+
__name(stalePushEntryError, "stalePushEntryError");
|
|
37504
38807
|
|
|
37505
38808
|
// src/commands/push.ts
|
|
37506
38809
|
function getDeployHint(type) {
|
|
@@ -37555,6 +38858,20 @@ async function authenticateOrFail() {
|
|
|
37555
38858
|
return requireAuthOrExit(false);
|
|
37556
38859
|
}
|
|
37557
38860
|
__name(authenticateOrFail, "authenticateOrFail");
|
|
38861
|
+
async function agentHasVersions() {
|
|
38862
|
+
try {
|
|
38863
|
+
const agentId = readYamlConfig()?.agent?.agentId;
|
|
38864
|
+
if (!agentId) return false;
|
|
38865
|
+
const apiKey = await requireAuthOrExit(false);
|
|
38866
|
+
const res = await new AgentVersionApi(BASE_URLS.API, apiKey, agentId).listVersions({
|
|
38867
|
+
limit: 1
|
|
38868
|
+
});
|
|
38869
|
+
return !!res.success && Array.isArray(res.data) && res.data.length > 0;
|
|
38870
|
+
} catch {
|
|
38871
|
+
return false;
|
|
38872
|
+
}
|
|
38873
|
+
}
|
|
38874
|
+
__name(agentHasVersions, "agentHasVersions");
|
|
37558
38875
|
async function selectEntityOrFail(items, options, config) {
|
|
37559
38876
|
const { entityType, nameFields = [
|
|
37560
38877
|
"id",
|
|
@@ -37635,7 +38952,6 @@ async function pushVersionedPrimitive(handler, options = {}) {
|
|
|
37635
38952
|
await compileCommand();
|
|
37636
38953
|
writeSuccess("\u2705 Compilation complete");
|
|
37637
38954
|
const apiKey = await authenticateOrFail();
|
|
37638
|
-
writeSuccess("\u2705 Authentication verified");
|
|
37639
38955
|
const config = readYamlConfig();
|
|
37640
38956
|
if (!config?.agent?.agentId) {
|
|
37641
38957
|
throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
|
|
@@ -37685,6 +39001,7 @@ async function pushVersionedPrimitive(handler, options = {}) {
|
|
|
37685
39001
|
version: confirmedVersion
|
|
37686
39002
|
});
|
|
37687
39003
|
if (!result.success) {
|
|
39004
|
+
if (result.statusCode === 404) throw stalePushEntryError(handler, selected.name, entityId, result.error);
|
|
37688
39005
|
const isVersionConflict = result.error?.toLowerCase().includes("already exists");
|
|
37689
39006
|
if (isVersionConflict) {
|
|
37690
39007
|
writeHintBlock({
|
|
@@ -37812,7 +39129,7 @@ async function pushCommand(type, cmdObj) {
|
|
|
37812
39129
|
autoDeployNoopWarned: isAutoDeployNoOp
|
|
37813
39130
|
});
|
|
37814
39131
|
}
|
|
37815
|
-
if (isGranular) {
|
|
39132
|
+
if (isGranular && await agentHasVersions()) {
|
|
37816
39133
|
writeInfo("\u26A0\uFE0F Granular push is deprecated when agent versioning is on. Use `lua push` (no args) to stage all changes, then `lua version create`.");
|
|
37817
39134
|
}
|
|
37818
39135
|
if (type === "all") {
|
|
@@ -38091,7 +39408,6 @@ Model: ${model}`);
|
|
|
38091
39408
|
}
|
|
38092
39409
|
}
|
|
38093
39410
|
const apiKey = await authenticateOrFail();
|
|
38094
|
-
writeProgress("\u2705 Authenticated");
|
|
38095
39411
|
const result = await agentHandler.pushAgentConfig(apiKey, agentId, manifest);
|
|
38096
39412
|
let productionDeployedWithAutoDeploy = false;
|
|
38097
39413
|
let personaDeployWasAttempted = false;
|
|
@@ -39830,70 +41146,6 @@ async function pushProcessorsToSandbox(apiKey, agentId, manifest, yamlConfig, is
|
|
|
39830
41146
|
}
|
|
39831
41147
|
__name(pushProcessorsToSandbox, "pushProcessorsToSandbox");
|
|
39832
41148
|
|
|
39833
|
-
// src/api/agent-version.api.service.ts
|
|
39834
|
-
init_http_client();
|
|
39835
|
-
var AgentVersionApi = class extends HttpClient {
|
|
39836
|
-
static {
|
|
39837
|
-
__name(this, "AgentVersionApi");
|
|
39838
|
-
}
|
|
39839
|
-
agentId;
|
|
39840
|
-
constructor(baseUrl, credential, agentId) {
|
|
39841
|
-
super(baseUrl, credential);
|
|
39842
|
-
this.agentId = agentId;
|
|
39843
|
-
}
|
|
39844
|
-
get basePath() {
|
|
39845
|
-
return `/developer/agents/${encodeURIComponent(this.agentId)}`;
|
|
39846
|
-
}
|
|
39847
|
-
get authHeader() {
|
|
39848
|
-
return {};
|
|
39849
|
-
}
|
|
39850
|
-
// ---------------------------------------------------------------------------
|
|
39851
|
-
// Version CRUD
|
|
39852
|
-
// ---------------------------------------------------------------------------
|
|
39853
|
-
async createVersion(body) {
|
|
39854
|
-
return this.httpPost(`${this.basePath}/versions`, body, this.authHeader);
|
|
39855
|
-
}
|
|
39856
|
-
async listVersions(query) {
|
|
39857
|
-
const params = new URLSearchParams();
|
|
39858
|
-
if (query?.all !== void 0) params.append("all", String(query.all));
|
|
39859
|
-
if (query?.limit !== void 0) params.append("limit", String(query.limit));
|
|
39860
|
-
if (query?.status !== void 0) params.append("status", query.status);
|
|
39861
|
-
const qs = params.toString();
|
|
39862
|
-
const url = qs ? `${this.basePath}/versions?${qs}` : `${this.basePath}/versions`;
|
|
39863
|
-
return this.httpGet(url, this.authHeader);
|
|
39864
|
-
}
|
|
39865
|
-
async getVersion(version) {
|
|
39866
|
-
return this.httpGet(`${this.basePath}/versions/${version}`, this.authHeader);
|
|
39867
|
-
}
|
|
39868
|
-
async deleteVersion(version) {
|
|
39869
|
-
return this.httpDelete(`${this.basePath}/versions/${version}`, this.authHeader);
|
|
39870
|
-
}
|
|
39871
|
-
// ---------------------------------------------------------------------------
|
|
39872
|
-
// Diff
|
|
39873
|
-
// ---------------------------------------------------------------------------
|
|
39874
|
-
async diffVersions(from, to) {
|
|
39875
|
-
const url = `${this.basePath}/versions/diff?from=${from}&to=${to}`;
|
|
39876
|
-
return this.httpGet(url, this.authHeader);
|
|
39877
|
-
}
|
|
39878
|
-
// ---------------------------------------------------------------------------
|
|
39879
|
-
// Promote
|
|
39880
|
-
// ---------------------------------------------------------------------------
|
|
39881
|
-
async promoteVersion(version) {
|
|
39882
|
-
return this.httpPost(`${this.basePath}/versions/${version}/promote`, {}, this.authHeader);
|
|
39883
|
-
}
|
|
39884
|
-
// ---------------------------------------------------------------------------
|
|
39885
|
-
// Patch commit hash — called by `lua version create` after a successful git
|
|
39886
|
-
// commit + tag to propagate the SHA to the backend AgentVersion record.
|
|
39887
|
-
// Failure is non-fatal; the version snapshot is valid whether or not this
|
|
39888
|
-
// PATCH lands.
|
|
39889
|
-
// ---------------------------------------------------------------------------
|
|
39890
|
-
async patchCommitHash(version, commitHash) {
|
|
39891
|
-
return this.httpPatch(`${this.basePath}/versions/${version}/commit-hash`, {
|
|
39892
|
-
commitHash
|
|
39893
|
-
}, this.authHeader);
|
|
39894
|
-
}
|
|
39895
|
-
};
|
|
39896
|
-
|
|
39897
41149
|
// src/commands/chat.ts
|
|
39898
41150
|
init_constants();
|
|
39899
41151
|
|
|
@@ -49002,6 +50254,7 @@ __name(formatSchedule2, "formatSchedule");
|
|
|
49002
50254
|
|
|
49003
50255
|
// src/commands/workflows.ts
|
|
49004
50256
|
init_cli();
|
|
50257
|
+
init_cli_error();
|
|
49005
50258
|
init_constants();
|
|
49006
50259
|
init_command_utils();
|
|
49007
50260
|
init_analytics();
|
|
@@ -49020,7 +50273,9 @@ var WORKFLOW_EXIT = {
|
|
|
49020
50273
|
RUN_CANCELLED: 5,
|
|
49021
50274
|
RUN_GATED: 6,
|
|
49022
50275
|
TIMEOUT: 7,
|
|
49023
|
-
RUN_PARKED: 8
|
|
50276
|
+
RUN_PARKED: 8,
|
|
50277
|
+
/** No server verdict — 5xx, connection refused, timeout: the global class (`errors/cli.error.ts`). */
|
|
50278
|
+
UNAVAILABLE: CLI_EXIT.UNAVAILABLE
|
|
49024
50279
|
};
|
|
49025
50280
|
var TERMINAL_FAILED = /* @__PURE__ */ new Set([
|
|
49026
50281
|
"failed",
|
|
@@ -49218,13 +50473,14 @@ __name(emitJson, "emitJson");
|
|
|
49218
50473
|
function apiFailure(ctx, res, verb) {
|
|
49219
50474
|
emitJson(ctx, res);
|
|
49220
50475
|
const err = res.error;
|
|
49221
|
-
const status = err?.statusCode
|
|
50476
|
+
const status = err?.statusCode;
|
|
49222
50477
|
const code = err?.code ?? err?.error;
|
|
49223
50478
|
if (!ctx.json) {
|
|
49224
50479
|
if (status === 503 && code === "CONTROL_UNAVAILABLE") console.error(`\u274C ${verb}: ${CONTROL_UNAVAILABLE_HINT}`);
|
|
49225
50480
|
else console.error(`\u274C ${verb} failed${code ? ` (${code})` : ""}: ${err?.message ?? "Unknown error"}`);
|
|
49226
50481
|
}
|
|
49227
50482
|
if (status === 404) return WORKFLOW_EXIT.NOT_FOUND;
|
|
50483
|
+
if (status === 0 || status !== void 0 && status >= 500) return WORKFLOW_EXIT.UNAVAILABLE;
|
|
49228
50484
|
return WORKFLOW_EXIT.API;
|
|
49229
50485
|
}
|
|
49230
50486
|
__name(apiFailure, "apiFailure");
|
|
@@ -49637,6 +50893,35 @@ async function statusCore(ctx, runId, o) {
|
|
|
49637
50893
|
return WORKFLOW_EXIT.OK;
|
|
49638
50894
|
}
|
|
49639
50895
|
__name(statusCore, "statusCore");
|
|
50896
|
+
function runMetering(run) {
|
|
50897
|
+
return run.usage?.metering === "priced" ? "priced" : "flat";
|
|
50898
|
+
}
|
|
50899
|
+
__name(runMetering, "runMetering");
|
|
50900
|
+
function budgetCopy(run) {
|
|
50901
|
+
if (runMetering(run) === "priced") {
|
|
50902
|
+
if (run.usage?.engine === "seat") return "charged like chat \u2014 actions (tier \xD7 model multiplier) per model call on your seat plan";
|
|
50903
|
+
if (run.usage?.engine === "legacy") return "charged like chat \u2014 one credit per model call on the legacy plan";
|
|
50904
|
+
return "charged like chat \u2014 one credit per model call on the legacy plan, or actions (tier \xD7 model multiplier) on a seat plan";
|
|
50905
|
+
}
|
|
50906
|
+
return "a credit is one agent step; a Job-tier attempt is 4 \u2014 tokens are never metered";
|
|
50907
|
+
}
|
|
50908
|
+
__name(budgetCopy, "budgetCopy");
|
|
50909
|
+
var fmtNum = /* @__PURE__ */ __name((v) => v.toLocaleString("en-US"), "fmtNum");
|
|
50910
|
+
function budgetLine(run) {
|
|
50911
|
+
const u = run.usage;
|
|
50912
|
+
const b = run.budget;
|
|
50913
|
+
if (!u && !b) return void 0;
|
|
50914
|
+
const seat = u?.engine === "seat" || b?.unit === "actions";
|
|
50915
|
+
const spent = seat ? u?.actionsUsed ?? b?.spent?.actionsEstimate ?? 0 : u?.creditsUsed ?? b?.spent?.credits ?? 0;
|
|
50916
|
+
const cap = runBudgetCap(b);
|
|
50917
|
+
const parts = [
|
|
50918
|
+
`${fmtNum(spent)}${cap !== void 0 ? ` of ${fmtNum(cap)}` : ""} ${seat ? "actions" : "credits"} spent`,
|
|
50919
|
+
b?.remaining !== void 0 ? `${fmtNum(b.remaining)} remaining` : void 0,
|
|
50920
|
+
seat && u?.creditsUsed ? `${fmtNum(u.creditsUsed)} flat credits` : void 0
|
|
50921
|
+
].filter((p) => !!p);
|
|
50922
|
+
return `${parts.join(" \xB7 ")} (${budgetCopy(run)})`;
|
|
50923
|
+
}
|
|
50924
|
+
__name(budgetLine, "budgetLine");
|
|
49640
50925
|
function printRun(run, withSteps) {
|
|
49641
50926
|
const id = runIdOf(run);
|
|
49642
50927
|
console.log(`
|
|
@@ -49646,6 +50931,8 @@ function printRun(run, withSteps) {
|
|
|
49646
50931
|
console.log(` Created: ${when(run.createdAt)}${run.startedAt ? ` \xB7 started ${when(run.startedAt)}` : ""}${run.completedAt ? ` \xB7 completed ${when(run.completedAt)}` : ""}`);
|
|
49647
50932
|
if (run.lineageId && run.lineageId !== id) console.log(` Lineage: ${run.lineageId}`);
|
|
49648
50933
|
if (run.parentRunId) console.log(` Parent: ${run.parentRunId} \u2014 lua workflows status ${run.parentRunId} --steps`);
|
|
50934
|
+
const budget = budgetLine(run);
|
|
50935
|
+
if (budget) console.log(` Budget: ${budget}`);
|
|
49649
50936
|
if (run.cancel) console.log(` Cancel: ${formatRunCancel(run.cancel)}`);
|
|
49650
50937
|
if (run.gate) {
|
|
49651
50938
|
const kind = run.gate.kind;
|
|
@@ -49654,7 +50941,8 @@ function printRun(run, withSteps) {
|
|
|
49654
50941
|
console.log(` lua workflows retry-step ${id} --step <id>`);
|
|
49655
50942
|
console.log(" To skip, complete or fail the step, or start a repair run, decide it from the desktop run page.");
|
|
49656
50943
|
} else if (kind === "budget") {
|
|
49657
|
-
console.log(
|
|
50944
|
+
console.log(`
|
|
50945
|
+
\u23F8\uFE0F Paused \u2014 run budget reached (${budgetCopy(run)}):`);
|
|
49658
50946
|
console.log(` lua workflows raise-budget ${id} --credits <n>`);
|
|
49659
50947
|
} else {
|
|
49660
50948
|
console.log(` Gate: ${kind}${run.gate.reason ? ` (${run.gate.reason})` : ""}${run.gate.since ? ` since ${when(run.gate.since)}` : ""}`);
|
|
@@ -49693,7 +50981,7 @@ function printRun(run, withSteps) {
|
|
|
49693
50981
|
s.stepId,
|
|
49694
50982
|
s.kind ?? "\u2014",
|
|
49695
50983
|
s.status,
|
|
49696
|
-
|
|
50984
|
+
stepAttemptCell(s),
|
|
49697
50985
|
stepErrorCell(s.error),
|
|
49698
50986
|
...withChildren ? [
|
|
49699
50987
|
s.childRunId ?? ""
|
|
@@ -49710,6 +50998,8 @@ function stepAttemptLines(s) {
|
|
|
49710
50998
|
if (cause) out.push(` \u2716 ${s.stepId}: ${cause}`);
|
|
49711
50999
|
const burned = cause ? void 0 : attemptCountersLine(s);
|
|
49712
51000
|
if (burned) out.push(` \u03A3 ${s.stepId}: attempt ${s.attempt ?? 1} ${s.status}: ${burned}`);
|
|
51001
|
+
const billed = stepBillingLine(s.billing);
|
|
51002
|
+
if (billed) out.push(` $ ${s.stepId}: attempt ${s.billing?.attempt ?? s.attempt ?? 1} billed: ${billed}`);
|
|
49713
51003
|
for (const a of s.attempts ?? []) {
|
|
49714
51004
|
if (a.status === "completed") continue;
|
|
49715
51005
|
const what = stepErrorCell(a.error) || a.killReason || "\u2014";
|
|
@@ -49719,6 +51009,33 @@ function stepAttemptLines(s) {
|
|
|
49719
51009
|
return out;
|
|
49720
51010
|
}
|
|
49721
51011
|
__name(stepAttemptLines, "stepAttemptLines");
|
|
51012
|
+
function stepAttemptCell(s) {
|
|
51013
|
+
const attempt = typeof s.attempt === "number" ? String(s.attempt) : "";
|
|
51014
|
+
if (typeof s.retriesRemaining === "number") {
|
|
51015
|
+
const left = s.retriesRemaining;
|
|
51016
|
+
return `${attempt} (${left === 0 ? "no retries" : left === 1 ? "1 retry" : `${left} retries`} left)`;
|
|
51017
|
+
}
|
|
51018
|
+
if (typeof s.maxAttempts === "number" && s.maxAttempts > 1 && attempt) return `${attempt}/${s.maxAttempts}`;
|
|
51019
|
+
return attempt;
|
|
51020
|
+
}
|
|
51021
|
+
__name(stepAttemptCell, "stepAttemptCell");
|
|
51022
|
+
function stepBillingLine(b) {
|
|
51023
|
+
if (!b) return void 0;
|
|
51024
|
+
const legs = [
|
|
51025
|
+
b.credits !== void 0 ? `${fmtNum(b.credits)} ${b.credits === 1 ? "credit" : "credits"}` : void 0,
|
|
51026
|
+
b.actions !== void 0 ? `${fmtNum(b.actions)} ${b.actions === 1 ? "action" : "actions"}` : void 0
|
|
51027
|
+
].filter((p) => !!p);
|
|
51028
|
+
const parts = [
|
|
51029
|
+
legs.length ? legs.join(" + ") : "no charge",
|
|
51030
|
+
b.engine === "seat" ? "seat plan" : "legacy plan",
|
|
51031
|
+
b.tier ? `${b.tier} tier${b.multiplier !== void 0 ? ` \xD7 ${fmtNum(b.multiplier)}` : ""}` : void 0,
|
|
51032
|
+
b.model ? `model ${b.model}` : void 0,
|
|
51033
|
+
b.byok ? "BYOK" : void 0,
|
|
51034
|
+
b.calibrated === false ? "uncalibrated model \u2014 fallback rate" : void 0
|
|
51035
|
+
].filter((p) => !!p);
|
|
51036
|
+
return parts.join(" \xB7 ");
|
|
51037
|
+
}
|
|
51038
|
+
__name(stepBillingLine, "stepBillingLine");
|
|
49722
51039
|
var RUN_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
49723
51040
|
"completed",
|
|
49724
51041
|
"failed",
|
|
@@ -49836,6 +51153,7 @@ async function watchCore(ctx, runId, o) {
|
|
|
49836
51153
|
} finally {
|
|
49837
51154
|
if (timer) clearTimeout(timer);
|
|
49838
51155
|
process.off("SIGINT", onSigint);
|
|
51156
|
+
if (!controller.signal.aborted) controller.abort();
|
|
49839
51157
|
}
|
|
49840
51158
|
if (exit !== void 0) return exit;
|
|
49841
51159
|
if (timedOut) {
|
|
@@ -49845,6 +51163,12 @@ async function watchCore(ctx, runId, o) {
|
|
|
49845
51163
|
return WORKFLOW_EXIT.OK;
|
|
49846
51164
|
}
|
|
49847
51165
|
__name(watchCore, "watchCore");
|
|
51166
|
+
function throttledLine(throttled) {
|
|
51167
|
+
return `throttled \xB7 ${[
|
|
51168
|
+
...throttled
|
|
51169
|
+
].map(([k, n2]) => `${k} \xD7${n2}`).join(" \xB7 ")}`;
|
|
51170
|
+
}
|
|
51171
|
+
__name(throttledLine, "throttledLine");
|
|
49848
51172
|
function handleWatchFrame(ctx, runId, frame, o, throttled) {
|
|
49849
51173
|
const data = frame.data ?? {};
|
|
49850
51174
|
if (o.events || ctx.json) console.log(JSON.stringify({
|
|
@@ -49852,6 +51176,12 @@ function handleWatchFrame(ctx, runId, frame, o, throttled) {
|
|
|
49852
51176
|
event: frame.event,
|
|
49853
51177
|
data: frame.data
|
|
49854
51178
|
}));
|
|
51179
|
+
const humanBoundary = /* @__PURE__ */ __name((line, code) => {
|
|
51180
|
+
if (!ctx.json) console.error(line);
|
|
51181
|
+
if (!o.waitForHuman) return code;
|
|
51182
|
+
if (!ctx.json) console.error(" --wait-for-human: still following \u2014 Ctrl+C or --timeout to stop");
|
|
51183
|
+
return void 0;
|
|
51184
|
+
}, "humanBoundary");
|
|
49855
51185
|
switch (frame.event) {
|
|
49856
51186
|
case "heartbeat":
|
|
49857
51187
|
return void 0;
|
|
@@ -49873,9 +51203,7 @@ function handleWatchFrame(ctx, runId, frame, o, throttled) {
|
|
|
49873
51203
|
if (type === "step.throttled") {
|
|
49874
51204
|
const kind = String(ev.data?.kind ?? "throttled");
|
|
49875
51205
|
throttled.set(kind, (throttled.get(kind) ?? 0) + 1);
|
|
49876
|
-
if (!ctx.json && !o.events) process.stdout.write(`\r
|
|
49877
|
-
...throttled
|
|
49878
|
-
].map(([k, n2]) => `${k} \xD7${n2}`).join(" \xB7 ")}`);
|
|
51206
|
+
if (!ctx.json && !o.events) process.stdout.write(`\r ${throttledLine(throttled)}`);
|
|
49879
51207
|
return void 0;
|
|
49880
51208
|
}
|
|
49881
51209
|
if (!ctx.json && !o.events) {
|
|
@@ -49887,29 +51215,30 @@ function handleWatchFrame(ctx, runId, frame, o, throttled) {
|
|
|
49887
51215
|
const detail = subrun ? ` \xB7 ${subrun}` : ev.data ? ` ${JSON.stringify(scrubEventData(ev.data)).slice(0, 160)}` : "";
|
|
49888
51216
|
console.log(`[${at}] ${type}${ev.stepId ? ` \xB7 ${ev.stepId}` : ""}${detail}`);
|
|
49889
51217
|
}
|
|
49890
|
-
if (type === "run.gated"
|
|
49891
|
-
|
|
49892
|
-
return WORKFLOW_EXIT.RUN_PARKED;
|
|
49893
|
-
}
|
|
49894
|
-
if (type === "run.gated" && ev.data?.gate === "billing") {
|
|
51218
|
+
if (type === "run.gated") {
|
|
51219
|
+
const gate = ev.data?.gate;
|
|
49895
51220
|
const stepId = ev.data?.stepId;
|
|
49896
|
-
if (
|
|
49897
|
-
|
|
51221
|
+
if (gate === "exception") {
|
|
51222
|
+
return humanBoundary(`\u26A0\uFE0F run parked on an exception gate \u2014 a human decides next: lua workflows status ${runId}`, WORKFLOW_EXIT.RUN_PARKED);
|
|
51223
|
+
}
|
|
51224
|
+
if (gate === "billing") {
|
|
51225
|
+
return humanBoundary(`\u23F8\uFE0F run parked on a billing gate \u2014 top up, then: lua workflows retry-step ${runId} --step ${stepId ?? "<stepId>"}`, WORKFLOW_EXIT.RUN_PARKED);
|
|
51226
|
+
}
|
|
51227
|
+
if (gate === "budget") {
|
|
51228
|
+
return humanBoundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (lua workflows status ${runId} says what a credit buys)`, WORKFLOW_EXIT.RUN_PARKED);
|
|
51229
|
+
}
|
|
51230
|
+
return humanBoundary(`\u23F8\uFE0F run gated (${gate ?? "consent"}) \u2014 approve it from the desktop; then: lua workflows watch ${runId}`, WORKFLOW_EXIT.RUN_GATED);
|
|
49898
51231
|
}
|
|
49899
51232
|
if (type === "run.suspended") {
|
|
49900
51233
|
const kind = ev.data?.kind;
|
|
49901
51234
|
const stepId = ev.data?.stepId ?? ev.stepId;
|
|
49902
51235
|
if (kind === "approval" || kind === "input" || kind === "signal") {
|
|
49903
|
-
|
|
49904
|
-
|
|
49905
|
-
console.error(`\u23F8\uFE0F run waits for a person (${kind}${stepId ? ` \xB7 ${stepId}` : ""}) \u2014 ${verb}; then: lua workflows watch ${runId}`);
|
|
49906
|
-
}
|
|
49907
|
-
return WORKFLOW_EXIT.RUN_PARKED;
|
|
51236
|
+
const verb = kind === "approval" ? `lua workflows approve ${runId} --approval <id> --decision approve|deny` : kind === "input" ? `lua workflows resume ${runId} --step ${stepId ?? "<stepId>"} --data <json>` : `lua workflows signal ${runId} <name> --payload <json>`;
|
|
51237
|
+
return humanBoundary(`\u23F8\uFE0F run waits for a person (${kind}${stepId ? ` \xB7 ${stepId}` : ""}) \u2014 ${verb}; then: lua workflows watch ${runId}`, WORKFLOW_EXIT.RUN_PARKED);
|
|
49908
51238
|
}
|
|
49909
51239
|
}
|
|
49910
51240
|
if (type === "run.budget_parked") {
|
|
49911
|
-
|
|
49912
|
-
return WORKFLOW_EXIT.RUN_PARKED;
|
|
51241
|
+
return humanBoundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (lua workflows status ${runId} says what a credit buys)`, WORKFLOW_EXIT.RUN_PARKED);
|
|
49913
51242
|
}
|
|
49914
51243
|
if (type === "run.completed") return WORKFLOW_EXIT.OK;
|
|
49915
51244
|
if (type === "run.failed" || type === "run.timed_out") return WORKFLOW_EXIT.RUN_FAILED;
|
|
@@ -49928,6 +51257,10 @@ async function cancelCore(ctx, runId, o) {
|
|
|
49928
51257
|
emitJson(ctx, res);
|
|
49929
51258
|
if (!ctx.json) {
|
|
49930
51259
|
const v = res.data;
|
|
51260
|
+
if (v.state === "terminal" || v.cancelRequested === false && v.transitioned === false && TERMINAL2.has(v.status)) {
|
|
51261
|
+
writeInfo(`\u2139\uFE0F run ${runId} was already ${v.status} \u2014 nothing to cancel`);
|
|
51262
|
+
return WORKFLOW_EXIT.OK;
|
|
51263
|
+
}
|
|
49931
51264
|
writeSuccess(`\u2705 cancel accepted \xB7 run ${runId} is ${v.status}`);
|
|
49932
51265
|
if (v.nextAction === "cancel_again") writeInfo(` next: cancel again to escalate \u2014 lua workflows cancel ${runId}`);
|
|
49933
51266
|
else if (v.nextAction === "force") writeInfo(` next: force available${v.forceAvailableAt ? ` at ${when(v.forceAvailableAt)}` : ""} \u2014 lua workflows cancel ${runId} --force`);
|
|
@@ -49980,8 +51313,8 @@ async function resumeCore(ctx, runId, o) {
|
|
|
49980
51313
|
if (!ctx.json) {
|
|
49981
51314
|
if (res.data.resumed) writeSuccess(`\u2705 resumed \xB7 run is ${res.data.runStatus}`);
|
|
49982
51315
|
else {
|
|
49983
|
-
const by = res.data.recorded?.by;
|
|
49984
|
-
writeInfo(`\u2139\uFE0F already resumed at ${when(res.data.recorded?.at)}${by ? ` by ${by
|
|
51316
|
+
const by = actorLabel(res.data.recorded?.by);
|
|
51317
|
+
writeInfo(`\u2139\uFE0F already resumed at ${when(res.data.recorded?.at)}${by ? ` by ${by}` : ""} \xB7 run is ${res.data.runStatus}`);
|
|
49985
51318
|
}
|
|
49986
51319
|
}
|
|
49987
51320
|
return WORKFLOW_EXIT.OK;
|
|
@@ -50014,13 +51347,20 @@ async function retryStepCore(ctx, runId, o) {
|
|
|
50014
51347
|
writeSuccess(`\u2705 re-armed ${o.step} (attempt ${d.attempt}) \xB7 run is ${d.runStatus}` + (d.remainingParks ? ` \xB7 ${d.remainingParks} other parked step(s)` : ""));
|
|
50015
51348
|
} else {
|
|
50016
51349
|
const standing = d.reason === "already_retried" ? "retried" : `resolved${d.recorded?.outcome ? ` (${d.recorded?.outcome})` : ""}`;
|
|
50017
|
-
const by = d.recorded?.by;
|
|
50018
|
-
writeInfo(`\u2139\uFE0F step "${o.step}" was already ${standing}` + (by ? ` by ${by
|
|
51350
|
+
const by = actorLabel(d.recorded?.by);
|
|
51351
|
+
writeInfo(`\u2139\uFE0F step "${o.step}" was already ${standing}` + (by ? ` by ${by}` : "") + (d.recorded?.at ? ` at ${when(d.recorded.at)}` : "") + ` \xB7 run is ${d.runStatus}`);
|
|
50019
51352
|
}
|
|
50020
51353
|
}
|
|
50021
51354
|
return WORKFLOW_EXIT.OK;
|
|
50022
51355
|
}
|
|
50023
51356
|
__name(retryStepCore, "retryStepCore");
|
|
51357
|
+
function approveResultLine(d) {
|
|
51358
|
+
if (d.resolved) return `\u2705 ${d.outcome} \xB7 run is ${d.runStatus}`;
|
|
51359
|
+
const ref = d.decidedBy;
|
|
51360
|
+
const who = ref && typeof ref === "object" && ref.subjectId && ref.source ? `${ref.subjectId} via ${ref.source}` : actorLabel(ref);
|
|
51361
|
+
return `\u2139\uFE0F no-op (${d.reason})${who ? ` \u2014 decided by ${who}` : ""}`;
|
|
51362
|
+
}
|
|
51363
|
+
__name(approveResultLine, "approveResultLine");
|
|
50024
51364
|
async function approveCore(ctx, runId, o) {
|
|
50025
51365
|
if (!o.approval) {
|
|
50026
51366
|
console.error("\u274C approve: --approval <id> is required");
|
|
@@ -50061,12 +51401,25 @@ async function approveCore(ctx, runId, o) {
|
|
|
50061
51401
|
}
|
|
50062
51402
|
emitJson(ctx, res);
|
|
50063
51403
|
if (!ctx.json) {
|
|
50064
|
-
if (res.data.resolved) writeSuccess(
|
|
50065
|
-
else writeInfo(
|
|
51404
|
+
if (res.data.resolved) writeSuccess(approveResultLine(res.data));
|
|
51405
|
+
else writeInfo(approveResultLine(res.data));
|
|
50066
51406
|
}
|
|
50067
51407
|
return WORKFLOW_EXIT.OK;
|
|
50068
51408
|
}
|
|
50069
51409
|
__name(approveCore, "approveCore");
|
|
51410
|
+
function actorLabel(by, now = Date.now()) {
|
|
51411
|
+
if (by === void 0 || by === null) return void 0;
|
|
51412
|
+
if (typeof by === "string") return by;
|
|
51413
|
+
if (typeof by !== "object") return String(by);
|
|
51414
|
+
const a = by;
|
|
51415
|
+
const kind = a.subjectType ?? a.kind;
|
|
51416
|
+
const id = a.name ?? a.subjectId ?? a.id;
|
|
51417
|
+
const who = kind && id ? `${kind}:${id}` : kind ?? id;
|
|
51418
|
+
if (!who) return void 0;
|
|
51419
|
+
const at = typeof a.at === "number" ? a.at : typeof a.at === "string" ? Date.parse(a.at) : NaN;
|
|
51420
|
+
return Number.isFinite(at) ? `${who} (${agoFrom(at, now)})` : who;
|
|
51421
|
+
}
|
|
51422
|
+
__name(actorLabel, "actorLabel");
|
|
50070
51423
|
function reservedSecretKeyPaths(value3, path25 = "", depth = 0, out = []) {
|
|
50071
51424
|
if (depth > 64 || out.length >= 20 || value3 === null || typeof value3 !== "object") return out;
|
|
50072
51425
|
if (Array.isArray(value3)) {
|
|
@@ -50345,6 +51698,17 @@ async function deleteCore(ctx, name, o) {
|
|
|
50345
51698
|
force: "cancel"
|
|
50346
51699
|
} : {});
|
|
50347
51700
|
if (!res.success) {
|
|
51701
|
+
if (res.error?.statusCode === 409 && (res.error.code ?? res.error.error) === "WORKFLOW_REFERENCED_BY_JOBS") {
|
|
51702
|
+
if (!ctx.json) {
|
|
51703
|
+
const jobs = res.error.jobs ?? [];
|
|
51704
|
+
console.error(`\u274C "${wf.name}" is still referenced by ${jobs.length} job(s) \u2014 stop them first:`);
|
|
51705
|
+
for (const j of jobs) {
|
|
51706
|
+
console.error(j.kind === "goal" && j.goalId ? ` \u2022 goal ${j.goalId} (job ${j.jobId}): lua workflows goals close ${j.goalId}` : ` \u2022 schedule ${j.jobId}: lua workflows schedules delete ${j.jobId}`);
|
|
51707
|
+
}
|
|
51708
|
+
}
|
|
51709
|
+
emitJson(ctx, res);
|
|
51710
|
+
return WORKFLOW_EXIT.API;
|
|
51711
|
+
}
|
|
50348
51712
|
if (res.error?.statusCode === 409 && !ctx.json) {
|
|
50349
51713
|
const counts = res.error.counts;
|
|
50350
51714
|
console.error(`\u274C "${wf.name}" has runs in flight${counts ? ` (${Object.entries(counts).map(([k, v]) => `${k}: ${v}`).join(", ")})` : ""} \u2014 cancel them first or pass --force`);
|
|
@@ -50678,10 +52042,14 @@ ${report.archived.length} archived \xB7 ${report.skipped.length} skipped \xB7 ${
|
|
|
50678
52042
|
__name(archiveRunsCore, "archiveRunsCore");
|
|
50679
52043
|
function ago(ms) {
|
|
50680
52044
|
if (!ms) return "\u2014";
|
|
50681
|
-
|
|
50682
|
-
return s < 90 ? `${s}s ago` : s < 5400 ? `${Math.round(s / 60)}m ago` : `${(s / 3600).toFixed(1)}h ago`;
|
|
52045
|
+
return agoFrom(ms, Date.now());
|
|
50683
52046
|
}
|
|
50684
52047
|
__name(ago, "ago");
|
|
52048
|
+
function agoFrom(ms, now) {
|
|
52049
|
+
const s = Math.max(0, Math.round((now - ms) / 1e3));
|
|
52050
|
+
return s < 90 ? `${s}s ago` : s < 5400 ? `${Math.round(s / 60)}m ago` : `${(s / 3600).toFixed(1)}h ago`;
|
|
52051
|
+
}
|
|
52052
|
+
__name(agoFrom, "agoFrom");
|
|
50685
52053
|
function printWorkspace(ws) {
|
|
50686
52054
|
console.log(`
|
|
50687
52055
|
\u{1F4E6} Workspace of ${ws.runId} \xB7 ${ws.status} (${ws.kind}, ${ws.backend})`);
|
|
@@ -50862,6 +52230,8 @@ var GOAL_VERBS = [
|
|
|
50862
52230
|
"list",
|
|
50863
52231
|
"get",
|
|
50864
52232
|
"create",
|
|
52233
|
+
"edit",
|
|
52234
|
+
"raise",
|
|
50865
52235
|
"pause",
|
|
50866
52236
|
"resume",
|
|
50867
52237
|
"close"
|
|
@@ -50903,6 +52273,10 @@ function parseIntegerFlag(v, flag, range2 = {}) {
|
|
|
50903
52273
|
return n2;
|
|
50904
52274
|
}
|
|
50905
52275
|
__name(parseIntegerFlag, "parseIntegerFlag");
|
|
52276
|
+
var GOAL_LIVE_STATUSES = /* @__PURE__ */ new Set([
|
|
52277
|
+
"active",
|
|
52278
|
+
"paused"
|
|
52279
|
+
]);
|
|
50906
52280
|
function goalScheduleRefusal(jobId, goalId) {
|
|
50907
52281
|
return `Schedule ${jobId} is the cadence of goal ${goalId} and was NOT removed \u2014 nothing was changed. To stop the goal use \`lua workflows goals pause ${goalId}\` (it can come back) or \`lua workflows goals close ${goalId}\` (final); unscheduling a goal's job is recorded as a failure of the goal, never as stopping it.`;
|
|
50908
52282
|
}
|
|
@@ -50927,7 +52301,12 @@ var judgeLabel = /* @__PURE__ */ __name((judge) => {
|
|
|
50927
52301
|
var goalStatusLabel = /* @__PURE__ */ __name((g) => `${g.status}${g.pauseReason ? ` (${g.pauseReason})` : ""}`, "goalStatusLabel");
|
|
50928
52302
|
var goalJobStateLabel = /* @__PURE__ */ __name((g) => g.job ? ` \xB7 ${g.job.status}${g.job.status === "active" && g.job.nextRunAt ? `, next ${when(g.job.nextRunAt)}` : ""}` : "", "goalJobStateLabel");
|
|
50929
52303
|
var verdictLabel = /* @__PURE__ */ __name((v) => v ? `${v.done ? "done" : "continue"}${v.summary ? ` \xB7 ${v.summary.slice(0, 60)}` : ""}` : "\u2014", "verdictLabel");
|
|
50930
|
-
var scheduleStatus = /* @__PURE__ */ __name((r) => r.autoDisabled ? "auto-disabled" : r.status === "inactive" ? "inactive" : r.paused ? "paused" : "active", "scheduleStatus");
|
|
52304
|
+
var scheduleStatus = /* @__PURE__ */ __name((r) => r.autoDisabled ? "auto-disabled" : r.status === "inactive" ? "inactive" : r.status === "completed" || r.status === "missed" ? r.status : r.paused ? "paused" : "active", "scheduleStatus");
|
|
52305
|
+
function goalRaiseHint(goalId, reason) {
|
|
52306
|
+
const flag = reason === "budget" ? "--max-credits <n>" : reason === "max_runs" ? "--max-runs <n>" : "--max-runs <n> | --max-credits <n>";
|
|
52307
|
+
return `a goal parked at its cap (max_runs / budget) re-arms when the cap is raised: lua workflows goals raise ${goalId} ${flag} \u2014 or edit it: lua workflows goals edit ${goalId} \u2026`;
|
|
52308
|
+
}
|
|
52309
|
+
__name(goalRaiseHint, "goalRaiseHint");
|
|
50931
52310
|
var errorLabel = /* @__PURE__ */ __name((e) => `${e.code ?? e.error ?? e.statusCode ?? "?"} \u2014 ${e.message}`, "errorLabel");
|
|
50932
52311
|
async function loadGoals(ctx, workflowId) {
|
|
50933
52312
|
const items = [];
|
|
@@ -51090,8 +52469,17 @@ function goalFailure(ctx, res, verb, ref) {
|
|
|
51090
52469
|
if (!ctx.json && err) {
|
|
51091
52470
|
if (status === 409 && code === "GOAL_NOT_ACTIVE") {
|
|
51092
52471
|
const now = err.status ?? "not active";
|
|
51093
|
-
const rule = verb === "goals resume" ? "only a paused goal resumes" : verb === "goals pause" ? "only an active goal pauses" : "a done/closed goal stays closed";
|
|
52472
|
+
const rule = verb === "goals resume" ? "only a paused goal resumes" : verb === "goals pause" ? "only an active goal pauses" : "a done/closed goal stays closed (a lingering cadence Job goes with `lua workflows schedules delete <jobId>`)";
|
|
51094
52473
|
console.error(`\u274C goal ${ref ?? ""} is ${now} \u2014 ${rule}`);
|
|
52474
|
+
if (verb === "goals resume" && now === "paused") console.error(` ${goalRaiseHint(ref ?? "<goalId>")}`);
|
|
52475
|
+
} else if (status === 400 && code === "GOAL_RAISE_BELOW_SPENT") {
|
|
52476
|
+
const { field, value: value3, spent } = err;
|
|
52477
|
+
const flag = field === "maxRuns" ? "--max-runs" : "--max-credits";
|
|
52478
|
+
const used = field === "maxRuns" ? "run(s) already used" : "credit(s) already spent";
|
|
52479
|
+
console.error(`\u274C ${flag} ${value3 ?? "?"} is not above the ${spent ?? "?"} ${used} \u2014 raise it past ${spent ?? "?"}`);
|
|
52480
|
+
} else if (status === 409 && code === "GOAL_VERSION_CONFLICT") {
|
|
52481
|
+
const at = err.updatedAt;
|
|
52482
|
+
console.error(`\u274C goal ${ref ?? ""} changed since it was read${at ? ` (updatedAt ${at})` : ""} \u2014 re-run lua workflows goals get ${ref ?? "<goalId>"} and retry${at ? ` with --if-match ${at}` : ""}`);
|
|
51095
52483
|
} else if (status === 409 && code === "GOAL_CAP") {
|
|
51096
52484
|
console.error(`\u274C goal cap reached (${err.cap ?? "?"} per agent) \u2014 close or finish one first: lua workflows goals list --status active`);
|
|
51097
52485
|
} else if (status === 400 && code === "VALIDATION_FAILED") {
|
|
@@ -51119,6 +52507,8 @@ async function goalsCore(ctx, target, extra, o) {
|
|
|
51119
52507
|
return WORKFLOW_EXIT.USAGE;
|
|
51120
52508
|
}
|
|
51121
52509
|
if (verb === "get") return goalsGetCore(ctx, extra);
|
|
52510
|
+
if (verb === "edit") return goalsEditCore(ctx, extra, o);
|
|
52511
|
+
if (verb === "raise") return goalsRaiseCore(ctx, extra, o);
|
|
51122
52512
|
return goalsControlCore(ctx, verb, extra, o);
|
|
51123
52513
|
}
|
|
51124
52514
|
__name(goalsCore, "goalsCore");
|
|
@@ -51188,6 +52578,10 @@ function printGoalDetail(g) {
|
|
|
51188
52578
|
console.log(` Cadence: ${cadenceLabel(g.cadence)} \xB7 mode ${g.evaluation?.mode ?? "immediate"}${g.evaluation?.delaySeconds ? ` \xB7 delay ${g.evaluation.delaySeconds}s` : ""}`);
|
|
51189
52579
|
console.log(` Runs: ${g.runsUsed}/${g.maxRuns} used \xB7 iteration ${g.iteration ?? 0}${g.consecutiveContinues ? ` \xB7 ${g.consecutiveContinues} consecutive continue(s)` : ""}${g.currentRunId ? ` \xB7 current ${g.currentRunId}` : ""}`);
|
|
51190
52580
|
if (g.budget?.maxCredits || g.maxTotalCredits) console.log(` Budget: ${g.budget?.maxCredits ? `per-run ${g.budget.maxCredits} credits` : ""}${g.budget?.maxCredits && g.maxTotalCredits ? " \xB7 " : ""}${g.maxTotalCredits ? `lineage cap ${g.maxTotalCredits} credits` : ""}`);
|
|
52581
|
+
if (g.status === "paused" && (g.pauseReason === "budget" || g.pauseReason === "max_runs")) console.log(` \u23F8 parked at its ${g.pauseReason === "budget" ? "credit" : "run"} cap \u2014 ${goalRaiseHint(g.goalId, g.pauseReason)}`);
|
|
52582
|
+
if (g.note) console.log(` Note: ${g.note}`);
|
|
52583
|
+
if (g.closeNote) console.log(` Closed: ${g.closeNote}`);
|
|
52584
|
+
if (g.raises?.length) console.log(` Raises: ${g.raises.map((r) => `${goalCapsLabel(r.from)} \u2192 ${goalCapsLabel(r.to)} (${r.by}, ${when(r.at)}${r.note ? `, "${r.note}"` : ""})`).join(" \xB7 ")}`);
|
|
51191
52585
|
console.log(` Schedule: ${g.jobId ? `${g.jobId} (goal-owned \u2014 stop it with goals pause|close, never schedules delete)${goalJobStateLabel(g)}` : "none (immediate)"}`);
|
|
51192
52586
|
if (g.verdict) console.log(` Verdict: ${verdictLabel(g.verdict)}${g.verdict.runId ? ` (run ${g.verdict.runId}${g.verdict.at ? ` at ${when(g.verdict.at)}` : ""})` : ""}`);
|
|
51193
52587
|
if (g.input !== void 0) console.log(` Input: ${JSON.stringify(g.input).slice(0, 500)}`);
|
|
@@ -51229,6 +52623,118 @@ async function goalsControlCore(ctx, verb, goalId, o) {
|
|
|
51229
52623
|
return WORKFLOW_EXIT.OK;
|
|
51230
52624
|
}
|
|
51231
52625
|
__name(goalsControlCore, "goalsControlCore");
|
|
52626
|
+
var goalCapsLabel = /* @__PURE__ */ __name((caps) => [
|
|
52627
|
+
caps.maxRuns !== void 0 ? `runs ${caps.maxRuns}` : "",
|
|
52628
|
+
caps.maxTotalCredits !== void 0 ? `credits ${caps.maxTotalCredits}` : ""
|
|
52629
|
+
].filter(Boolean).join(" \xB7 ") || "\u2014", "goalCapsLabel");
|
|
52630
|
+
function parseEveryFlag(raw) {
|
|
52631
|
+
const m = /^\s*(\d+)\s*(s|sec|secs|m|min|mins|h|hr|hrs)?\s*$/i.exec(String(raw));
|
|
52632
|
+
if (!m) throw new WorkflowLocalUsageError("usage", `--every: expected <seconds>, <n>m or <n>h (got "${raw}")`);
|
|
52633
|
+
const n2 = Number(m[1]);
|
|
52634
|
+
const unit = (m[2] ?? "s").toLowerCase();
|
|
52635
|
+
const seconds = unit.startsWith("h") ? n2 * 3600 : unit.startsWith("m") ? n2 * 60 : n2;
|
|
52636
|
+
if (seconds < 60 || seconds % 60 !== 0) throw new WorkflowLocalUsageError("usage", `--every: the interval must be whole minutes, at least 60s (got ${seconds}s)`);
|
|
52637
|
+
return [
|
|
52638
|
+
{
|
|
52639
|
+
type: "interval",
|
|
52640
|
+
seconds
|
|
52641
|
+
}
|
|
52642
|
+
];
|
|
52643
|
+
}
|
|
52644
|
+
__name(parseEveryFlag, "parseEveryFlag");
|
|
52645
|
+
function printGoalWriteSummary(g, past) {
|
|
52646
|
+
writeSuccess(`\u2705 goal ${g.goalId} ${past} \xB7 ${goalStatusLabel(g)} \xB7 runs ${g.runsUsed}/${g.maxRuns}${g.maxTotalCredits ? ` \xB7 lineage cap ${g.maxTotalCredits} credits` : ""}${g.jobId ? ` \xB7 schedule ${g.jobId}${goalJobStateLabel(g)}` : ""}`);
|
|
52647
|
+
if (g.rearmed) writeInfo(" \u21BA re-armed \u2014 the cap park cleared and the goal is active again (no backfill)");
|
|
52648
|
+
if (g.resumed === false) writeInfo(` \u26A0\uFE0F the goal parked again (${g.pauseReason ?? "strikes"}) \u2014 see: lua workflows goals get ${g.goalId}`);
|
|
52649
|
+
if (!g.rearmed && g.status === "paused" && (g.pauseReason === "budget" || g.pauseReason === "max_runs")) writeInfo(` still parked (${g.pauseReason}) \u2014 ${goalRaiseHint(g.goalId, g.pauseReason)}`);
|
|
52650
|
+
}
|
|
52651
|
+
__name(printGoalWriteSummary, "printGoalWriteSummary");
|
|
52652
|
+
async function goalsEditCore(ctx, goalId, o) {
|
|
52653
|
+
let dto;
|
|
52654
|
+
try {
|
|
52655
|
+
const usage = /* @__PURE__ */ __name((m) => new WorkflowLocalUsageError("usage", m), "usage");
|
|
52656
|
+
dto = {};
|
|
52657
|
+
if (o.objective !== void 0) {
|
|
52658
|
+
if (!o.objective.trim()) throw usage("--objective: must not be empty");
|
|
52659
|
+
dto.objective = o.objective.trim();
|
|
52660
|
+
}
|
|
52661
|
+
if (o.judgePredicate) dto.judge = {
|
|
52662
|
+
agentId: "$self",
|
|
52663
|
+
predicate: parseJudgePredicateFlag(o.judgePredicate)
|
|
52664
|
+
};
|
|
52665
|
+
if (o.every && o.cadence?.length) throw usage("--every and --cadence are alternatives \u2014 pass one");
|
|
52666
|
+
if (o.every) dto.cadence = parseEveryFlag(o.every);
|
|
52667
|
+
else if (o.cadence?.length) dto.cadence = parseCadenceFlag(o.cadence, o.timezone);
|
|
52668
|
+
else if (o.timezone) throw usage("--timezone applies to a bare cron --cadence entry \u2014 none given");
|
|
52669
|
+
const maxRuns = parseIntegerFlag(o.maxRuns, "--max-runs", {
|
|
52670
|
+
min: 1,
|
|
52671
|
+
max: GOAL_MAX_RUNS_CAP
|
|
52672
|
+
});
|
|
52673
|
+
if (maxRuns !== void 0) dto.maxRuns = maxRuns;
|
|
52674
|
+
const rawCredits = o.maxCredits ?? o.maxTotalCredits;
|
|
52675
|
+
if (rawCredits !== void 0) {
|
|
52676
|
+
if (String(rawCredits).trim().toLowerCase() === "none") dto.maxTotalCredits = null;
|
|
52677
|
+
else dto.maxTotalCredits = parseIntegerFlag(rawCredits, "--max-credits", {
|
|
52678
|
+
min: 1
|
|
52679
|
+
});
|
|
52680
|
+
}
|
|
52681
|
+
if (o.note !== void 0) dto.note = o.note.trim() ? o.note : null;
|
|
52682
|
+
const ifMatch = parseIntegerFlag(o.ifMatch, "--if-match", {
|
|
52683
|
+
min: 1
|
|
52684
|
+
});
|
|
52685
|
+
if (ifMatch !== void 0) dto.ifMatch = ifMatch;
|
|
52686
|
+
if (Object.keys(dto).filter((k) => k !== "ifMatch").length === 0) throw usage("nothing to change \u2014 pass --objective, --judge-predicate, --cadence | --every, --max-runs, --max-credits <n|none> or --note");
|
|
52687
|
+
} catch (e) {
|
|
52688
|
+
if (e instanceof WorkflowLocalUsageError) {
|
|
52689
|
+
console.error(`\u274C goals edit: ${e.message}`);
|
|
52690
|
+
return WORKFLOW_EXIT.USAGE;
|
|
52691
|
+
}
|
|
52692
|
+
throw e;
|
|
52693
|
+
}
|
|
52694
|
+
const res = await ctx.api.updateGoal(goalId, dto);
|
|
52695
|
+
if (!res.success || !res.data) return goalFailure(ctx, res, "goals edit", goalId);
|
|
52696
|
+
emitJson(ctx, res);
|
|
52697
|
+
if (!ctx.json) printGoalWriteSummary(res.data, "updated");
|
|
52698
|
+
return WORKFLOW_EXIT.OK;
|
|
52699
|
+
}
|
|
52700
|
+
__name(goalsEditCore, "goalsEditCore");
|
|
52701
|
+
async function goalsRaiseCore(ctx, goalId, o) {
|
|
52702
|
+
let dto;
|
|
52703
|
+
try {
|
|
52704
|
+
dto = {};
|
|
52705
|
+
const maxRuns = parseIntegerFlag(o.maxRuns, "--max-runs", {
|
|
52706
|
+
min: 1,
|
|
52707
|
+
max: GOAL_MAX_RUNS_CAP
|
|
52708
|
+
});
|
|
52709
|
+
if (maxRuns !== void 0) dto.maxRuns = maxRuns;
|
|
52710
|
+
const maxTotalCredits = parseIntegerFlag(o.maxCredits ?? o.maxTotalCredits, "--max-credits", {
|
|
52711
|
+
min: 1
|
|
52712
|
+
});
|
|
52713
|
+
if (maxTotalCredits !== void 0) dto.maxTotalCredits = maxTotalCredits;
|
|
52714
|
+
if (dto.maxRuns === void 0 && dto.maxTotalCredits === void 0) throw new WorkflowLocalUsageError("usage", "--max-credits <n> and/or --max-runs <n> is required (increases only)");
|
|
52715
|
+
if (o.note) dto.note = o.note;
|
|
52716
|
+
const ifMatch = parseIntegerFlag(o.ifMatch, "--if-match", {
|
|
52717
|
+
min: 1
|
|
52718
|
+
});
|
|
52719
|
+
if (ifMatch !== void 0) dto.ifMatch = ifMatch;
|
|
52720
|
+
} catch (e) {
|
|
52721
|
+
if (e instanceof WorkflowLocalUsageError) {
|
|
52722
|
+
console.error(`\u274C goals raise: ${e.message}`);
|
|
52723
|
+
return WORKFLOW_EXIT.USAGE;
|
|
52724
|
+
}
|
|
52725
|
+
throw e;
|
|
52726
|
+
}
|
|
52727
|
+
const res = await ctx.api.raiseGoal(goalId, dto);
|
|
52728
|
+
if (!res.success || !res.data) return goalFailure(ctx, res, "goals raise", goalId);
|
|
52729
|
+
emitJson(ctx, res);
|
|
52730
|
+
if (!ctx.json) {
|
|
52731
|
+
const g = res.data;
|
|
52732
|
+
const last = g.raises?.[g.raises.length - 1];
|
|
52733
|
+
printGoalWriteSummary(g, `raised${last ? ` (${goalCapsLabel(last.from)} \u2192 ${goalCapsLabel(last.to)})` : ""}`);
|
|
52734
|
+
}
|
|
52735
|
+
return WORKFLOW_EXIT.OK;
|
|
52736
|
+
}
|
|
52737
|
+
__name(goalsRaiseCore, "goalsRaiseCore");
|
|
51232
52738
|
function parseJudgePredicateFlag(raw) {
|
|
51233
52739
|
const opList = GOAL_PREDICATE_OPS.join("|");
|
|
51234
52740
|
if (raw.startsWith("{") || raw.startsWith("@")) {
|
|
@@ -51465,7 +52971,15 @@ async function schedulesDeleteCore(ctx, jobId, o) {
|
|
|
51465
52971
|
if (!rowRes.success || !rowRes.data) return apiFailure(ctx, rowRes, "schedules delete");
|
|
51466
52972
|
const row2 = rowRes.data;
|
|
51467
52973
|
let goalId = row2.goalId;
|
|
51468
|
-
|
|
52974
|
+
let goalStatus;
|
|
52975
|
+
if (goalId) {
|
|
52976
|
+
const goalRes = await ctx.api.getGoal(goalId);
|
|
52977
|
+
if (goalRes.success && goalRes.data) goalStatus = goalRes.data.status;
|
|
52978
|
+
else if (goalRes.error?.statusCode !== 404) {
|
|
52979
|
+
if (!ctx.json) console.error(`\u274C cannot prove goal ${goalId} of ${jobId} has ended (goal unreadable) \u2014 refusing to delete`);
|
|
52980
|
+
return apiFailure(ctx, goalRes, "schedules delete");
|
|
52981
|
+
}
|
|
52982
|
+
} else {
|
|
51469
52983
|
const goals = await loadGoals(ctx, row2.workflowId);
|
|
51470
52984
|
if (goals.error) {
|
|
51471
52985
|
if (!ctx.json) console.error(`\u274C cannot prove ${jobId} is not a goal's cadence (goals unavailable) \u2014 refusing to delete`);
|
|
@@ -51474,9 +52988,11 @@ async function schedulesDeleteCore(ctx, jobId, o) {
|
|
|
51474
52988
|
error: goals.error
|
|
51475
52989
|
}, "schedules delete");
|
|
51476
52990
|
}
|
|
51477
|
-
|
|
52991
|
+
const owner = goals.items.find((g) => g.jobId === jobId);
|
|
52992
|
+
goalId = owner?.goalId;
|
|
52993
|
+
goalStatus = owner?.status;
|
|
51478
52994
|
}
|
|
51479
|
-
if (goalId) {
|
|
52995
|
+
if (goalId && GOAL_LIVE_STATUSES.has(goalStatus)) {
|
|
51480
52996
|
const message = goalScheduleRefusal(jobId, goalId);
|
|
51481
52997
|
if (ctx.json) console.log(JSON.stringify({
|
|
51482
52998
|
success: false,
|
|
@@ -60387,6 +61903,7 @@ import chalk4 from "chalk";
|
|
|
60387
61903
|
init_compiler2();
|
|
60388
61904
|
init_artifact_loader();
|
|
60389
61905
|
init_analytics();
|
|
61906
|
+
init_cli_error();
|
|
60390
61907
|
async function resolveCurrentModel(apiKey, agentId) {
|
|
60391
61908
|
const serverModel = await fetchServerModel(apiKey, agentId);
|
|
60392
61909
|
if (serverModel) return serverModel;
|
|
@@ -60450,8 +61967,9 @@ async function modelsCommand(action, opts) {
|
|
|
60450
61967
|
const models = await fetchApprovedModels(apiKey, agentId);
|
|
60451
61968
|
writeProgress("");
|
|
60452
61969
|
if (models === null) {
|
|
60453
|
-
|
|
60454
|
-
|
|
61970
|
+
throw new CliError("error", "Could not fetch models from the server.", {
|
|
61971
|
+
hint: "Check your connection and API key, then retry."
|
|
61972
|
+
});
|
|
60455
61973
|
}
|
|
60456
61974
|
if (models.length === 0) {
|
|
60457
61975
|
writeInfo("\u2139\uFE0F No models are currently available. If your organization restricts models, an admin may need to review its excluded-models list.");
|
|
@@ -62992,23 +64510,30 @@ Examples:
|
|
|
62992
64510
|
$ lua jobs versions -i myJob View job versions
|
|
62993
64511
|
$ lua jobs history -i myJob View execution history
|
|
62994
64512
|
`).action(jobsCommand);
|
|
62995
|
-
program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, approve, signal, replay)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/goals create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list: page size").option("--cursor <c>", "runs/goals list: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch: give up after s seconds (exit 7)").option("--events", "watch: print raw frames").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/logs: step id").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve: approval id").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip)").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create: cadence entry (repeatable, \u2264 5); none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create: IANA timezone for bare cron cadences").option("--max-runs <n>", "goals create: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").addHelpText("after", `
|
|
64513
|
+
program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, approve, signal, replay)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/goals create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list: page size").option("--cursor <c>", "runs/goals list: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch / start --follow: give up after s seconds while the run is still live (exit 7)").option("--events", "watch: print raw frames").option("--wait-for-human", "watch / start --follow: keep following through a human boundary (approval, input, signal, park) instead of exiting 8").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/logs: step id").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve: approval id").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip)").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create: cadence entry (repeatable, \u2264 5); none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create/edit: IANA timezone for bare cron cadences").option("--max-runs <n>", "goals create/edit/raise: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").option("--max-credits <n|none>", "goals edit/raise: lineage-wide credit gate (edit: none clears it)").option("--every <interval>", "goals edit: interval cadence \u2014 900, 15m, 2h (whole minutes, \u2265 60s)").option("--if-match <updatedAt>", "goals edit/raise: refuse the write if the goal changed since this updatedAt").addHelpText("after", `
|
|
62996
64514
|
Arguments:
|
|
62997
64515
|
action list \xB7 view \xB7 versions \xB7 deploy \xB7 activate \xB7 deactivate \xB7 start \xB7 run \xB7 runs \xB7 status \xB7
|
|
62998
64516
|
watch \xB7 cancel \xB7 resume \xB7 retry-step \xB7 approve \xB7 signal \xB7 replay \xB7 logs \xB7 delete \xB7 delete-run \xB7
|
|
62999
64517
|
env-overlay \xB7 archive-runs \xB7 workspace \xB7 jobs \xB7 job-logs \xB7
|
|
63000
|
-
goals <list|get|create|pause|resume|close> \xB7 schedules <list|delete>
|
|
64518
|
+
goals <list|get|create|edit|raise|pause|resume|close> \xB7 schedules <list|delete>
|
|
63001
64519
|
target workflow name (list/view/versions/deploy/activate/deactivate/start/run/delete) or run id (the rest);
|
|
63002
64520
|
the sub-verb for goals / schedules
|
|
63003
|
-
extra signal name (signal <runId> <name>) \xB7 goal id (goals get/pause/resume/close) \xB7 job id (schedules delete)
|
|
64521
|
+
extra signal name (signal <runId> <name>) \xB7 goal id (goals get/edit/raise/pause/resume/close) \xB7 job id (schedules delete)
|
|
63004
64522
|
|
|
63005
|
-
Exit codes: 0 ok \xB7 1 API
|
|
63006
|
-
6 run gated (consent) \xB7 7 --timeout reached \xB7 8 run parked
|
|
64523
|
+
Exit codes: 0 ok \xB7 1 API refusal (a 4xx other than 404) \xB7 2 usage \xB7 3 not found \xB7 4 run failed \xB7 5 run cancelled \xB7
|
|
64524
|
+
6 run gated (consent) \xB7 7 --timeout reached \xB7 8 run parked \u2014 waiting for a human
|
|
64525
|
+
(approval \xB7 input \xB7 signal \xB7 billing / budget / exception park; the resuming verb is printed).
|
|
64526
|
+
start --follow and watch EXIT at a human boundary (8, or 6 on a consent gate) unless
|
|
64527
|
+
--wait-for-human; a terminal run exits 0 completed \xB7 4 failed/timed out \xB7 5 cancelled.
|
|
64528
|
+
A failed request and every escaped error use the global classes: 9 auth (401) \xB7 10 forbidden (403) \xB7
|
|
64529
|
+
11 unavailable (5xx / connection refused / timeout) \u2014 one line, \u2716 <code>: <message>; LUA_DEBUG=1
|
|
64530
|
+
prints the stack.
|
|
63007
64531
|
|
|
63008
64532
|
Examples:
|
|
63009
64533
|
$ lua workflows list
|
|
63010
64534
|
$ lua workflows run outreach --input @leads.json --step-output draftEmail=@draft.json --approve reviewDrafts
|
|
63011
64535
|
$ lua workflows start outreach --input '{"leads":[]}' --follow
|
|
64536
|
+
$ lua workflows start outreach --follow --wait-for-human --timeout 3600
|
|
63012
64537
|
$ lua workflows runs --workflow outreach --status failed
|
|
63013
64538
|
$ lua workflows status <runId> --steps
|
|
63014
64539
|
$ lua workflows watch <runId> --timeout 600
|
|
@@ -63029,6 +64554,8 @@ Examples:
|
|
|
63029
64554
|
$ lua workflows goals get wfg_1234
|
|
63030
64555
|
$ lua workflows goals create -i outreach --objective "Reach 50 signups" --judge-predicate 'output.signups gte 50' \\
|
|
63031
64556
|
--cadence '0 9 * * 1' --timezone Europe/London --max-runs 12 --input '{"segment":"trial"}'
|
|
64557
|
+
$ lua workflows goals edit wfg_1234 --max-credits 500 --every 30m --note "widened after the launch"
|
|
64558
|
+
$ lua workflows goals raise wfg_1234 --max-runs 24 (a goal parked max_runs / budget re-arms when its cap clears)
|
|
63032
64559
|
$ lua workflows goals pause wfg_1234 \xB7 goals resume wfg_1234 \xB7 goals close wfg_1234 --note "shipped"
|
|
63033
64560
|
$ lua workflows schedules list -i outreach
|
|
63034
64561
|
$ lua workflows schedules delete <jobId> --yes (a goal's cadence is refused: goal_schedule)
|
|
@@ -63370,6 +64897,7 @@ __name(setupSkillCommands, "setupSkillCommands");
|
|
|
63370
64897
|
|
|
63371
64898
|
// src/index.ts
|
|
63372
64899
|
init_cli();
|
|
64900
|
+
init_cli_error();
|
|
63373
64901
|
|
|
63374
64902
|
// src/utils/banner.ts
|
|
63375
64903
|
var BOLD = "\x1B[1m";
|
|
@@ -63414,8 +64942,9 @@ if (isBareInvocation || isHelpInvocation) {
|
|
|
63414
64942
|
version: CLI_VERSION
|
|
63415
64943
|
});
|
|
63416
64944
|
}
|
|
64945
|
+
if (args.includes("--debug") || debugEnabled()) setDebugMode(true);
|
|
63417
64946
|
var program = new Command();
|
|
63418
|
-
program.showSuggestionAfterError().name("lua").description("Lua AI - Build and deploy AI agents with superpowers").version(CLI_VERSION, "-V, --cli-version").option("--ci", "CI/CD mode: fail loudly on missing required flags instead of prompting").addHelpText("after", `
|
|
64947
|
+
program.exitOverride().showSuggestionAfterError().name("lua").description("Lua AI - Build and deploy AI agents with superpowers").version(CLI_VERSION, "-V, --cli-version").option("--ci", "CI/CD mode: fail loudly on missing required flags instead of prompting").addHelpText("after", `
|
|
63419
64948
|
Categories:
|
|
63420
64949
|
\u{1F510} Authentication Manage API keys and authentication
|
|
63421
64950
|
\u{1F680} Project Setup Initialize and configure projects
|
|
@@ -63460,6 +64989,8 @@ Examples:
|
|
|
63460
64989
|
$ lua marketplace \u{1F6CD}\uFE0F Interact with the Lua Marketplace (skills & agent templates)
|
|
63461
64990
|
$ lua marketplace template \u{1F9E9} Create, publish, and apply marketplace agent templates
|
|
63462
64991
|
|
|
64992
|
+
${CLI_EXIT_CODE_HELP}
|
|
64993
|
+
|
|
63463
64994
|
\u{1F319} Documentation: https://docs.heylua.ai
|
|
63464
64995
|
\u{1F319} Support: https://heylua.ai/support
|
|
63465
64996
|
`);
|
|
@@ -63477,5 +65008,7 @@ if (rawArgs.length === 1 && rawArgs[0] === "--version") {
|
|
|
63477
65008
|
console.log(CLI_VERSION);
|
|
63478
65009
|
process.exit(0);
|
|
63479
65010
|
}
|
|
63480
|
-
program.
|
|
65011
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
65012
|
+
reportUnhandledCliError(error);
|
|
65013
|
+
});
|
|
63481
65014
|
//# sourceMappingURL=index.js.map
|