lua-cli 3.38.0 → 3.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-exports.d.ts +100 -18
- package/dist/api-exports.js +1445 -285
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +2424 -558
- package/dist/index.js.map +1 -1
- package/dist/voice/test/index.d.ts +18 -18
- package/dist/workflow-builder.js +1379 -243
- package/dist/workflow-builder.js.map +1 -1
- package/docs/CLI_REFERENCE.md +16 -1
- package/package.json +6 -5
- package/template/package.json +1 -1
package/dist/api-exports.js
CHANGED
|
@@ -18,6 +18,7 @@ var __export = (target, all) => {
|
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
import { z as z2 } from "zod";
|
|
20
20
|
import { z as z3 } from "zod";
|
|
21
|
+
import { z as z4 } from "zod";
|
|
21
22
|
function isChannelConversationChannel(channel) {
|
|
22
23
|
return !!channel && CHANNEL_CONVERSATION_CHANNELS.includes(channel);
|
|
23
24
|
}
|
|
@@ -114,9 +115,9 @@ function isMcpDraftCreateTool(tool) {
|
|
|
114
115
|
function mcpSendSiblingForDraftTool(tool, availableToolIds) {
|
|
115
116
|
const candidates = [
|
|
116
117
|
...availableToolIds
|
|
117
|
-
].filter((
|
|
118
|
-
id,
|
|
119
|
-
serverName:
|
|
118
|
+
].filter((id2) => id2.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX)).map((id2) => ({
|
|
119
|
+
id: id2,
|
|
120
|
+
serverName: id2.slice(0, -REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length)
|
|
120
121
|
})).filter(({ serverName }) => tool.startsWith(`${serverName}_`)).sort((a, b) => b.serverName.length - a.serverName.length);
|
|
121
122
|
return candidates[0]?.id;
|
|
122
123
|
}
|
|
@@ -277,8 +278,8 @@ function transformChatHistoryContentParts(parts) {
|
|
|
277
278
|
}
|
|
278
279
|
return content;
|
|
279
280
|
}
|
|
280
|
-
function isSyntheticSideRow(
|
|
281
|
-
return
|
|
281
|
+
function isSyntheticSideRow(id2) {
|
|
282
|
+
return id2.startsWith(SCREENSHOT_MESSAGE_ID_PREFIX) || id2.startsWith(RICH_PARTS_MESSAGE_ID_PREFIX);
|
|
282
283
|
}
|
|
283
284
|
function mergeRichPartMirrorMessages(messages, sameTurnGroup) {
|
|
284
285
|
const merged = [];
|
|
@@ -359,6 +360,155 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
|
|
|
359
360
|
while (next < synthetic.length) combined.push(synthetic[next++].message);
|
|
360
361
|
return mergeRichPartMirrorMessages(combined, sameTurnGroup);
|
|
361
362
|
}
|
|
363
|
+
function utf8WidthAt(value3, index) {
|
|
364
|
+
const code = value3.charCodeAt(index);
|
|
365
|
+
if (code < 128) return {
|
|
366
|
+
bytes: 1,
|
|
367
|
+
units: 1
|
|
368
|
+
};
|
|
369
|
+
if (code < 2048) return {
|
|
370
|
+
bytes: 2,
|
|
371
|
+
units: 1
|
|
372
|
+
};
|
|
373
|
+
if (code >= 55296 && code <= 56319) {
|
|
374
|
+
const next = value3.charCodeAt(index + 1);
|
|
375
|
+
if (next >= 56320 && next <= 57343) return {
|
|
376
|
+
bytes: 4,
|
|
377
|
+
units: 2
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return {
|
|
381
|
+
bytes: 3,
|
|
382
|
+
units: 1
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function utf8ByteLength(value3) {
|
|
386
|
+
let bytes = 0;
|
|
387
|
+
for (let i = 0; i < value3.length; ) {
|
|
388
|
+
const width = utf8WidthAt(value3, i);
|
|
389
|
+
bytes += width.bytes;
|
|
390
|
+
i += width.units;
|
|
391
|
+
}
|
|
392
|
+
return bytes;
|
|
393
|
+
}
|
|
394
|
+
function clampUtf8(value3, maxBytes) {
|
|
395
|
+
let bytes = 0;
|
|
396
|
+
for (let i = 0; i < value3.length; ) {
|
|
397
|
+
const width = utf8WidthAt(value3, i);
|
|
398
|
+
if (bytes + width.bytes > maxBytes) return value3.slice(0, i);
|
|
399
|
+
bytes += width.bytes;
|
|
400
|
+
i += width.units;
|
|
401
|
+
}
|
|
402
|
+
return value3;
|
|
403
|
+
}
|
|
404
|
+
function mapBytes(fields, withMark) {
|
|
405
|
+
return utf8ByteLength(JSON.stringify(withMark ? {
|
|
406
|
+
...fields,
|
|
407
|
+
[LOG_FIELDS_CLAMPED_KEY]: true
|
|
408
|
+
} : fields));
|
|
409
|
+
}
|
|
410
|
+
function withValueCap(fields, capBytes) {
|
|
411
|
+
const out = {};
|
|
412
|
+
for (const [key, value3] of Object.entries(fields)) {
|
|
413
|
+
out[key] = typeof value3 === "string" ? clampUtf8(value3, capBytes) : value3;
|
|
414
|
+
}
|
|
415
|
+
return out;
|
|
416
|
+
}
|
|
417
|
+
function describeValue(value3) {
|
|
418
|
+
if (value3 === null) return "null";
|
|
419
|
+
if (value3 === void 0) return "undefined";
|
|
420
|
+
if (Array.isArray(value3)) return "an array";
|
|
421
|
+
return typeof value3 === "object" ? "an object" : `a ${typeof value3}`;
|
|
422
|
+
}
|
|
423
|
+
function assertValidLogFieldKey(key) {
|
|
424
|
+
if (!LOG_FIELD_KEY_PATTERN.test(key)) {
|
|
425
|
+
throw new LuaLogFieldsError(`log fields: key \`${key}\` is not allowed \u2014 a key must match ${LOG_FIELD_KEY_PATTERN.source} (lower-case, starts with a letter, then letters/digits/underscore, at most 64 characters)`);
|
|
426
|
+
}
|
|
427
|
+
if (LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS.some((pattern) => pattern.test(key))) {
|
|
428
|
+
throw new LuaLogFieldsError(`log fields: key \`${key}\` is not allowed \u2014 it has the shape of a credential that the log-drain scrubber masks in values; a field KEY is never scrubbed, so it may never carry a secret shape`);
|
|
429
|
+
}
|
|
430
|
+
if (key === LOG_FIELDS_CLAMPED_KEY) {
|
|
431
|
+
throw new LuaLogFieldsError(`log fields: key \`${key}\` is reserved \u2014 the platform sets it to mark a field map it had to clamp`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function normalizeLogFields(fields) {
|
|
435
|
+
if (fields === void 0 || fields === null) return void 0;
|
|
436
|
+
if (typeof fields !== "object" || Array.isArray(fields)) {
|
|
437
|
+
throw new LuaLogFieldsError(`log fields: expected a plain object of fields, received ${describeValue(fields)}`);
|
|
438
|
+
}
|
|
439
|
+
const entries = Object.entries(fields);
|
|
440
|
+
if (entries.length > LOG_FIELDS_MAX_KEYS) {
|
|
441
|
+
throw new LuaLogFieldsError(`log fields: ${entries.length} keys exceeds the cap of ${LOG_FIELDS_MAX_KEYS} keys per call`);
|
|
442
|
+
}
|
|
443
|
+
const out = {};
|
|
444
|
+
for (const [key, value3] of entries) {
|
|
445
|
+
assertValidLogFieldKey(key);
|
|
446
|
+
if (typeof value3 === "string" || typeof value3 === "boolean") {
|
|
447
|
+
out[key] = value3;
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
if (typeof value3 === "number") {
|
|
451
|
+
if (!Number.isFinite(value3)) {
|
|
452
|
+
throw new LuaLogFieldsError(`log fields: \`${key}\` must be a finite number \u2014 NaN and Infinity have no JSON form`);
|
|
453
|
+
}
|
|
454
|
+
out[key] = value3;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (Array.isArray(value3)) {
|
|
458
|
+
const parts = [];
|
|
459
|
+
for (const element of value3) {
|
|
460
|
+
if (typeof element !== "string") {
|
|
461
|
+
throw new LuaLogFieldsError(`log fields: \`${key}\` is an array, so every element must be a string (found ${describeValue(element)})`);
|
|
462
|
+
}
|
|
463
|
+
if (element.includes(",")) {
|
|
464
|
+
throw new LuaLogFieldsError(`log fields: \`${key}\` \u2014 an array element may not contain a comma; elements are comma-joined into one value (with \`${key}${LOG_FIELD_ARRAY_COUNT_SUFFIX}\` beside it), so a comma inside one would be indistinguishable from the separator`);
|
|
465
|
+
}
|
|
466
|
+
parts.push(element);
|
|
467
|
+
}
|
|
468
|
+
out[key] = parts.join(",");
|
|
469
|
+
out[`${key}${LOG_FIELD_ARRAY_COUNT_SUFFIX}`] = parts.length;
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
throw new LuaLogFieldsError(`log fields: \`${key}\` must be a string, number, boolean or string[] \u2014 received ${describeValue(value3)}` + (value3 !== null && typeof value3 === "object" ? " (nested objects are not supported)" : ""));
|
|
473
|
+
}
|
|
474
|
+
const keys = Object.keys(out);
|
|
475
|
+
if (keys.length === 0) return void 0;
|
|
476
|
+
if (keys.length > LOG_FIELDS_MAX_KEYS) {
|
|
477
|
+
throw new LuaLogFieldsError(`log fields: ${keys.length} keys exceeds the cap of ${LOG_FIELDS_MAX_KEYS} keys per call \u2014 an array field also contributes its \`${LOG_FIELD_ARRAY_COUNT_SUFFIX.slice(1)}\` sibling`);
|
|
478
|
+
}
|
|
479
|
+
if (clampLogFields(out)) out[LOG_FIELDS_CLAMPED_KEY] = true;
|
|
480
|
+
return out;
|
|
481
|
+
}
|
|
482
|
+
function clampLogFields(out) {
|
|
483
|
+
let clamped = false;
|
|
484
|
+
for (const [key, value3] of Object.entries(out)) {
|
|
485
|
+
if (typeof value3 !== "string") continue;
|
|
486
|
+
const capped = clampUtf8(value3, LOG_FIELD_MAX_VALUE_BYTES);
|
|
487
|
+
if (capped !== value3) {
|
|
488
|
+
out[key] = capped;
|
|
489
|
+
clamped = true;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (mapBytes(out, clamped) <= LOG_FIELDS_MAX_BYTES) return clamped;
|
|
493
|
+
const base = {
|
|
494
|
+
...out
|
|
495
|
+
};
|
|
496
|
+
let low = 0;
|
|
497
|
+
let high = LOG_FIELD_MAX_VALUE_BYTES;
|
|
498
|
+
let best = 0;
|
|
499
|
+
while (low <= high) {
|
|
500
|
+
const mid = Math.floor((low + high) / 2);
|
|
501
|
+
if (mapBytes(withValueCap(base, mid), true) <= LOG_FIELDS_MAX_BYTES) {
|
|
502
|
+
best = mid;
|
|
503
|
+
low = mid + 1;
|
|
504
|
+
} else {
|
|
505
|
+
high = mid - 1;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
const fitted = withValueCap(base, best);
|
|
509
|
+
for (const key of Object.keys(out)) out[key] = fitted[key];
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
362
512
|
function isDesktopFileCommandName(value3) {
|
|
363
513
|
return typeof value3 === "string" && DESKTOP_FILE_COMMAND_SET.has(value3);
|
|
364
514
|
}
|
|
@@ -449,12 +599,12 @@ function isWorkflowArmEntryType(type) {
|
|
|
449
599
|
function workflowContainerRunsHitlArm(container) {
|
|
450
600
|
return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
|
|
451
601
|
}
|
|
452
|
-
function workflowHitlArmUnsupportedMessage(type,
|
|
602
|
+
function workflowHitlArmUnsupportedMessage(type, id2, container) {
|
|
453
603
|
const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
|
|
454
|
-
return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${
|
|
604
|
+
return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${id2}") \u2014 place it at the top level, as a ${legal} arm, or inside a child \`workflow\``;
|
|
455
605
|
}
|
|
456
|
-
function workflowHitlArmShapeMessage(type,
|
|
457
|
-
return shape === "mapped-arm" ? `\`${type}\` arm "${
|
|
606
|
+
function workflowHitlArmShapeMessage(type, id2, shape) {
|
|
607
|
+
return shape === "mapped-arm" ? `\`${type}\` arm "${id2}" takes the previous output as its payload \u2014 it cannot head a [mapping, step] chain; map before the container instead` : `a chunked foreach hands each child a slice of items, not one \u2014 \`${type}\` body "${id2}" takes one item; drop \`chunk\``;
|
|
458
608
|
}
|
|
459
609
|
function isModelIdSentinel(input) {
|
|
460
610
|
const lower = (input ?? "").trim().toLowerCase();
|
|
@@ -586,6 +736,81 @@ function buildDefaultPersona(agentName) {
|
|
|
586
736
|
function buildPersonalSpaceStartingPersona(agentName) {
|
|
587
737
|
return PERSONAL_SPACE_STARTING_PERSONA.replace(new RegExp(AGENT_NAME_TOKEN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), () => agentName || "Your assistant");
|
|
588
738
|
}
|
|
739
|
+
function utf8Bytes(value3) {
|
|
740
|
+
let bytes = 0;
|
|
741
|
+
for (let i = 0; i < value3.length; ) {
|
|
742
|
+
const code = value3.charCodeAt(i);
|
|
743
|
+
if (code < 128) {
|
|
744
|
+
bytes += 1;
|
|
745
|
+
i += 1;
|
|
746
|
+
} else if (code < 2048) {
|
|
747
|
+
bytes += 2;
|
|
748
|
+
i += 1;
|
|
749
|
+
} else if (code >= 55296 && code <= 56319) {
|
|
750
|
+
const next = value3.charCodeAt(i + 1);
|
|
751
|
+
if (next >= 56320 && next <= 57343) {
|
|
752
|
+
bytes += 4;
|
|
753
|
+
i += 2;
|
|
754
|
+
} else {
|
|
755
|
+
bytes += 3;
|
|
756
|
+
i += 1;
|
|
757
|
+
}
|
|
758
|
+
} else {
|
|
759
|
+
bytes += 3;
|
|
760
|
+
i += 1;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return bytes;
|
|
764
|
+
}
|
|
765
|
+
function isPlainFieldKey(key) {
|
|
766
|
+
if (!LOG_FIELD_KEY_PATTERN.test(key)) return false;
|
|
767
|
+
return !LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS.some((pattern) => pattern.test(key));
|
|
768
|
+
}
|
|
769
|
+
function describeAgentLogFieldsViolation(value3) {
|
|
770
|
+
if (typeof value3 !== "object" || value3 === null || Array.isArray(value3)) {
|
|
771
|
+
return "fields must be an object";
|
|
772
|
+
}
|
|
773
|
+
const entries = Object.entries(value3);
|
|
774
|
+
let userKeys = 0;
|
|
775
|
+
for (const [key, entry] of entries) {
|
|
776
|
+
if (key === LOG_FIELDS_CLAMPED_KEY) {
|
|
777
|
+
if (entry !== true) return `fields.${key} must be true`;
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
userKeys += 1;
|
|
781
|
+
if (key.endsWith(LOG_FIELD_ARRAY_COUNT_SUFFIX)) {
|
|
782
|
+
const base = key.slice(0, -LOG_FIELD_ARRAY_COUNT_SUFFIX.length);
|
|
783
|
+
if (!isPlainFieldKey(base)) return `fields key \`${key}\` is not a legal field key`;
|
|
784
|
+
if (typeof entry !== "number" || !Number.isFinite(entry)) {
|
|
785
|
+
return `fields.${key} must be a finite number`;
|
|
786
|
+
}
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (!isPlainFieldKey(key)) return `fields key \`${key}\` is not a legal field key`;
|
|
790
|
+
if (typeof entry === "string") {
|
|
791
|
+
if (utf8Bytes(entry) > LOG_FIELD_MAX_VALUE_BYTES) {
|
|
792
|
+
return `fields.${key} exceeds ${LOG_FIELD_MAX_VALUE_BYTES} bytes`;
|
|
793
|
+
}
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
if (typeof entry === "boolean") continue;
|
|
797
|
+
if (typeof entry === "number") {
|
|
798
|
+
if (!Number.isFinite(entry)) return `fields.${key} must be a finite number`;
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
return `fields.${key} must be a string, number or boolean`;
|
|
802
|
+
}
|
|
803
|
+
if (userKeys > LOG_FIELDS_MAX_KEYS) {
|
|
804
|
+
return `fields has ${userKeys} keys, over the cap of ${LOG_FIELDS_MAX_KEYS}`;
|
|
805
|
+
}
|
|
806
|
+
if (utf8Bytes(JSON.stringify(value3)) > LOG_FIELDS_MAX_BYTES) {
|
|
807
|
+
return `fields exceeds ${LOG_FIELDS_MAX_BYTES} bytes`;
|
|
808
|
+
}
|
|
809
|
+
return void 0;
|
|
810
|
+
}
|
|
811
|
+
function isAgentLogFields(value3) {
|
|
812
|
+
return describeAgentLogFieldsViolation(value3) === void 0;
|
|
813
|
+
}
|
|
589
814
|
function maxDrainsForTier(tier) {
|
|
590
815
|
return tier === "enterprise" ? LOG_DRAIN_MAX_PER_ORG_ENTERPRISE : LOG_DRAIN_MAX_PER_ORG;
|
|
591
816
|
}
|
|
@@ -594,6 +819,148 @@ function resolvePresetEndpoint(type, site) {
|
|
|
594
819
|
if (!template3 || !site) return void 0;
|
|
595
820
|
return template3.replace("{site}", site);
|
|
596
821
|
}
|
|
822
|
+
function isLogDrainBucketHostAllowed(provider, host) {
|
|
823
|
+
const normalized = host.trim().toLowerCase().replace(/^\[|\]$/g, "");
|
|
824
|
+
if (!normalized) return false;
|
|
825
|
+
return (LOG_DRAIN_BUCKET_HOST_PATTERNS[provider] ?? []).some((pattern) => pattern.test(normalized));
|
|
826
|
+
}
|
|
827
|
+
function resolveDrainBucketEndpoint(bucket) {
|
|
828
|
+
if (!LOG_DRAIN_BUCKET_NAME_PATTERN.test(bucket.bucket)) {
|
|
829
|
+
throw new Error("log drain bucket name is not a valid S3 bucket label");
|
|
830
|
+
}
|
|
831
|
+
if (bucket.provider === "aws") {
|
|
832
|
+
const region = bucket.region.trim().toLowerCase();
|
|
833
|
+
if (!/^[a-z0-9-]{1,32}$/.test(region)) throw new Error("log drain bucket region is not an AWS region");
|
|
834
|
+
return `https://${bucket.bucket}.s3.${region}.amazonaws.com`;
|
|
835
|
+
}
|
|
836
|
+
if (!bucket.endpoint) throw new Error(`log drain '${bucket.provider}' bucket requires an endpoint`);
|
|
837
|
+
let url;
|
|
838
|
+
try {
|
|
839
|
+
url = new URL(bucket.endpoint);
|
|
840
|
+
} catch {
|
|
841
|
+
throw new Error(`log drain '${bucket.provider}' bucket endpoint is not an absolute URL`);
|
|
842
|
+
}
|
|
843
|
+
if (url.protocol !== "https:") throw new Error(`log drain '${bucket.provider}' bucket endpoint must be https`);
|
|
844
|
+
return `https://${url.host}/${bucket.bucket}`;
|
|
845
|
+
}
|
|
846
|
+
function drainBucketUsesPathStyle(provider) {
|
|
847
|
+
return provider !== "aws";
|
|
848
|
+
}
|
|
849
|
+
function presetIntakeHosts(type) {
|
|
850
|
+
const template3 = LOG_DRAIN_ENDPOINT_TEMPLATES[type];
|
|
851
|
+
const sites = LOG_DRAIN_PRESET_SITES[type];
|
|
852
|
+
if (!template3 || !sites) return [];
|
|
853
|
+
const hosts = [];
|
|
854
|
+
for (const site of sites) {
|
|
855
|
+
try {
|
|
856
|
+
hosts.push(new URL(template3.replace("{site}", site)).hostname.toLowerCase());
|
|
857
|
+
} catch {
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
return hosts;
|
|
861
|
+
}
|
|
862
|
+
function presetHostAllowlist(type) {
|
|
863
|
+
return [
|
|
864
|
+
...presetIntakeHosts(type),
|
|
865
|
+
...LOG_DRAIN_PRESET_HOST_SUFFIXES[type] ?? []
|
|
866
|
+
];
|
|
867
|
+
}
|
|
868
|
+
function drainHostAllowlistAllows(allowlist, host) {
|
|
869
|
+
const needle = host.toLowerCase();
|
|
870
|
+
return allowlist.some((raw) => {
|
|
871
|
+
const entry = raw.toLowerCase();
|
|
872
|
+
if (entry.startsWith(".")) return needle === entry.slice(1) || needle.endsWith(entry);
|
|
873
|
+
return entry === needle;
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
function drainDestinationIsVendorPinned(type) {
|
|
877
|
+
if (LOG_DRAIN_ENDPOINT_TEMPLATES[type]) return true;
|
|
878
|
+
return presetHostAllowlist(type).length > 0;
|
|
879
|
+
}
|
|
880
|
+
function drainVerificationOwnership(input) {
|
|
881
|
+
if (input.proved === true) return "verified";
|
|
882
|
+
if (input.mode === "test-post" && drainDestinationIsVendorPinned(input.type)) return "verified";
|
|
883
|
+
return "reachability-only";
|
|
884
|
+
}
|
|
885
|
+
function drainOwnershipOrDefault(ownership) {
|
|
886
|
+
return ownership === "verified" ? "verified" : "reachability-only";
|
|
887
|
+
}
|
|
888
|
+
function assertDrainContentAck(input) {
|
|
889
|
+
const turningOn = input.next === true && input.was !== true;
|
|
890
|
+
if (!turningOn) return void 0;
|
|
891
|
+
if (input.ack !== true) throw new DrainContentAckRequiredError();
|
|
892
|
+
return {
|
|
893
|
+
by: input.actor,
|
|
894
|
+
source: input.source,
|
|
895
|
+
at: input.at,
|
|
896
|
+
...input.inheritedFrom ? {
|
|
897
|
+
inheritedFrom: input.inheritedFrom
|
|
898
|
+
} : {}
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
function composePresetEndpoint(type, endpoint) {
|
|
902
|
+
const rule = LOG_DRAIN_PRESET_PATHS[type];
|
|
903
|
+
if (!rule) return void 0;
|
|
904
|
+
let url;
|
|
905
|
+
try {
|
|
906
|
+
url = new URL(endpoint);
|
|
907
|
+
} catch {
|
|
908
|
+
return {
|
|
909
|
+
ok: false,
|
|
910
|
+
reason: "invalid_url"
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
if (url.protocol !== "https:" || !url.hostname) return {
|
|
914
|
+
ok: false,
|
|
915
|
+
reason: "invalid_url"
|
|
916
|
+
};
|
|
917
|
+
const origin = url.origin;
|
|
918
|
+
const path3 = url.pathname.replace(/\/+$/, "");
|
|
919
|
+
if (!rule.segment) {
|
|
920
|
+
const base2 = path3.endsWith(rule.path) ? path3.slice(0, path3.length - rule.path.length) : path3;
|
|
921
|
+
return {
|
|
922
|
+
ok: true,
|
|
923
|
+
endpoint: `${origin}${base2}${rule.path}`
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
const marker = `${rule.path}/`;
|
|
927
|
+
const at = path3.indexOf(marker);
|
|
928
|
+
if (at < 0) {
|
|
929
|
+
return {
|
|
930
|
+
ok: false,
|
|
931
|
+
reason: rule.segment === "dataset" ? "missing_dataset" : "missing_token"
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
const base = path3.slice(0, at);
|
|
935
|
+
const afterMarker = path3.slice(at + marker.length);
|
|
936
|
+
const rest = rule.suffix && afterMarker.endsWith(rule.suffix) ? afterMarker.slice(0, afterMarker.length - rule.suffix.length) : afterMarker;
|
|
937
|
+
if (!rest || rest.includes("/")) {
|
|
938
|
+
return {
|
|
939
|
+
ok: false,
|
|
940
|
+
reason: rule.segment === "dataset" ? "missing_dataset" : "missing_token"
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
if (!PRESET_SEGMENT_RE.test(rest)) return {
|
|
944
|
+
ok: false,
|
|
945
|
+
reason: "bad_segment"
|
|
946
|
+
};
|
|
947
|
+
if (rule.segment === "dataset") {
|
|
948
|
+
return {
|
|
949
|
+
ok: true,
|
|
950
|
+
endpoint: `${origin}${base}${rule.path}/${rest}${rule.suffix ?? ""}`,
|
|
951
|
+
dataset: rest
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
return {
|
|
955
|
+
ok: true,
|
|
956
|
+
endpoint: `${origin}${base}${rule.path}/`,
|
|
957
|
+
token: rest
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
function joinPresetEndpointToken(endpoint, token) {
|
|
961
|
+
if (typeof token !== "string" || !PRESET_SEGMENT_RE.test(token)) return endpoint;
|
|
962
|
+
return endpoint.endsWith("/") ? `${endpoint}${token}` : `${endpoint}/${token}`;
|
|
963
|
+
}
|
|
597
964
|
function nextLogDrainQuotaResetAt(now) {
|
|
598
965
|
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)).toISOString();
|
|
599
966
|
}
|
|
@@ -640,6 +1007,264 @@ function logDrainQuotaDroppedSeverities(degradation) {
|
|
|
640
1007
|
return [];
|
|
641
1008
|
}
|
|
642
1009
|
}
|
|
1010
|
+
function isLogExportSource(source) {
|
|
1011
|
+
return LOG_EXPORT_SOURCES.includes(source);
|
|
1012
|
+
}
|
|
1013
|
+
function clamp(value3, max) {
|
|
1014
|
+
if (typeof value3 !== "string") return void 0;
|
|
1015
|
+
const trimmed = value3.trim();
|
|
1016
|
+
if (!trimmed) return void 0;
|
|
1017
|
+
return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max - 1)}\u2026`;
|
|
1018
|
+
}
|
|
1019
|
+
function numberOr(value3, fallback) {
|
|
1020
|
+
return typeof value3 === "number" && Number.isFinite(value3) ? value3 : fallback;
|
|
1021
|
+
}
|
|
1022
|
+
function isoOr(value3) {
|
|
1023
|
+
return typeof value3 === "string" && value3.length > 0 ? value3 : void 0;
|
|
1024
|
+
}
|
|
1025
|
+
function logDrainNoticeView(drain, now) {
|
|
1026
|
+
const health = drain.health ?? {};
|
|
1027
|
+
const quota = drain.quota;
|
|
1028
|
+
const view = {
|
|
1029
|
+
id: String(drain.id ?? ""),
|
|
1030
|
+
name: String(drain.name ?? ""),
|
|
1031
|
+
type: drain.type,
|
|
1032
|
+
state: drain.state,
|
|
1033
|
+
deliveredCount24h: numberOr(health.deliveredCount24h, 0),
|
|
1034
|
+
droppedCount24h: numberOr(health.droppedCount24h, 0),
|
|
1035
|
+
rejectedCount24h: numberOr(health.rejectedCount24h, 0),
|
|
1036
|
+
backlog: numberOr(health.backlog, 0),
|
|
1037
|
+
quotaRatio: quota ? logDrainQuotaRatio(quota, now) : 0
|
|
1038
|
+
};
|
|
1039
|
+
if (health.pauseReason) view.pauseReason = health.pauseReason;
|
|
1040
|
+
const lastError = clamp(health.lastError, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS);
|
|
1041
|
+
if (lastError) view.lastError = lastError;
|
|
1042
|
+
if (typeof health.lastStatusCode === "number") view.lastStatusCode = health.lastStatusCode;
|
|
1043
|
+
const lastSuccessAt = isoOr(health.lastSuccessAt);
|
|
1044
|
+
if (lastSuccessAt) view.lastSuccessAt = lastSuccessAt;
|
|
1045
|
+
const lastFailureAt = isoOr(health.lastFailureAt);
|
|
1046
|
+
if (lastFailureAt) view.lastFailureAt = lastFailureAt;
|
|
1047
|
+
const resetsAt = isoOr(quota?.resetsAt);
|
|
1048
|
+
if (resetsAt) view.quotaResetsAt = resetsAt;
|
|
1049
|
+
return view;
|
|
1050
|
+
}
|
|
1051
|
+
function logDrainHealthCardPath(orgId, drainId) {
|
|
1052
|
+
return `/orgs/${encodeURIComponent(orgId)}/log-drains/${encodeURIComponent(drainId)}`;
|
|
1053
|
+
}
|
|
1054
|
+
function percent(ratio) {
|
|
1055
|
+
if (!Number.isFinite(ratio) || ratio <= 0) return "0%";
|
|
1056
|
+
return `${Math.round(ratio * 100)}%`;
|
|
1057
|
+
}
|
|
1058
|
+
function becauseClause(view) {
|
|
1059
|
+
const bits = [];
|
|
1060
|
+
if (view.lastStatusCode) bits.push(`HTTP ${view.lastStatusCode}`);
|
|
1061
|
+
if (view.lastError) bits.push(view.lastError);
|
|
1062
|
+
return bits.length ? ` Last error: ${bits.join(" \u2014 ")}.` : "";
|
|
1063
|
+
}
|
|
1064
|
+
function logDrainNoticeCopy(payload) {
|
|
1065
|
+
const view = payload.drain;
|
|
1066
|
+
const name = view.name || view.id;
|
|
1067
|
+
const backlog = view.backlog > 0 ? ` ${view.backlog.toLocaleString("en-US")} records are buffered.` : "";
|
|
1068
|
+
switch (payload.kind) {
|
|
1069
|
+
case "failing":
|
|
1070
|
+
return {
|
|
1071
|
+
title: name,
|
|
1072
|
+
subject: `Log drain "${name}" is failing`,
|
|
1073
|
+
previewLine: "Failing \u2014 15 minutes without a successful delivery",
|
|
1074
|
+
summary: `The log drain "${name}" (${view.type}) has gone 15 minutes without a successful delivery and is now failing.${becauseClause(view)}${backlog} Records keep buffering; the drain pauses itself after 24 hours without a success.`,
|
|
1075
|
+
status: "failed",
|
|
1076
|
+
priority: "high"
|
|
1077
|
+
};
|
|
1078
|
+
case "paused_auto":
|
|
1079
|
+
return {
|
|
1080
|
+
title: name,
|
|
1081
|
+
subject: `Log drain "${name}" was paused`,
|
|
1082
|
+
previewLine: "Paused \u2014 24 hours without a successful delivery",
|
|
1083
|
+
summary: `The log drain "${name}" (${view.type}) was paused automatically after 24 hours without a successful delivery.${becauseClause(view)}${backlog} Nothing is being sent while it is paused, and the buffer is delivered on resume. Fix the destination, then resume it from the drain's health card or with \`lua drains resume ${view.id}\`.`,
|
|
1084
|
+
status: "failed",
|
|
1085
|
+
priority: "high"
|
|
1086
|
+
};
|
|
1087
|
+
case "paused_quota":
|
|
1088
|
+
return {
|
|
1089
|
+
title: name,
|
|
1090
|
+
subject: `Log drain "${name}" was paused \u2014 daily quota exhausted`,
|
|
1091
|
+
previewLine: `Paused \u2014 ${percent(view.quotaRatio)} of the daily allowance used`,
|
|
1092
|
+
summary: `The log drain "${name}" (${view.type}) reached ${percent(view.quotaRatio)} of its daily allowance and was paused.${backlog} Records keep buffering. The allowance resets${view.quotaResetsAt ? ` at ${view.quotaResetsAt}` : " at 00:00 UTC"}; narrow the drain's sources or raise the plan's limit to stop it happening again, then resume it with \`lua drains resume ${view.id}\`.`,
|
|
1093
|
+
status: "failed",
|
|
1094
|
+
priority: "high"
|
|
1095
|
+
};
|
|
1096
|
+
case "quota_warning":
|
|
1097
|
+
return {
|
|
1098
|
+
title: name,
|
|
1099
|
+
subject: `Log drain "${name}" has used 80% of its daily allowance`,
|
|
1100
|
+
previewLine: `${percent(view.quotaRatio)} of the daily allowance used`,
|
|
1101
|
+
summary: `The log drain "${name}" (${view.type}) has used ${percent(view.quotaRatio)} of today's allowance. Past 100% debug records are dropped, past 125% info records as well, and at 150% the drain pauses. The allowance resets${view.quotaResetsAt ? ` at ${view.quotaResetsAt}` : " at 00:00 UTC"}.`,
|
|
1102
|
+
status: "failed",
|
|
1103
|
+
priority: "normal"
|
|
1104
|
+
};
|
|
1105
|
+
case "dropped": {
|
|
1106
|
+
const dropped = payload.droppedCount ?? view.droppedCount24h;
|
|
1107
|
+
return {
|
|
1108
|
+
title: name,
|
|
1109
|
+
subject: `Log drain "${name}" is dropping records`,
|
|
1110
|
+
previewLine: `${dropped.toLocaleString("en-US")} records dropped`,
|
|
1111
|
+
summary: `The log drain "${name}" (${view.type}) dropped ${dropped.toLocaleString("en-US")} records because its buffer filled up faster than the destination accepted them.${becauseClause(view)} The gap is reported in band on the next successful batch, so the range is recoverable from the destination itself.`,
|
|
1112
|
+
status: "failed",
|
|
1113
|
+
priority: "high"
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
case "verification_pending":
|
|
1117
|
+
return {
|
|
1118
|
+
title: name,
|
|
1119
|
+
subject: `Log drain "${name}" is still unverified`,
|
|
1120
|
+
previewLine: "Unverified after 24 hours \u2014 nothing is being delivered",
|
|
1121
|
+
summary: `The log drain "${name}" (${view.type}) was created more than 24 hours ago and has never completed verification, so nothing is being delivered to it.${becauseClause(view)} Run \`lua drains verify ${view.id}\` once the destination echoes the verification token.`,
|
|
1122
|
+
status: "failed",
|
|
1123
|
+
priority: "normal"
|
|
1124
|
+
};
|
|
1125
|
+
default: {
|
|
1126
|
+
const exhaustive = payload.kind;
|
|
1127
|
+
throw new Error(`unhandled log-drain notice kind: ${String(exhaustive)}`);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function logDrainNoticeLabel(kind) {
|
|
1132
|
+
switch (kind) {
|
|
1133
|
+
case "failing":
|
|
1134
|
+
return "failing";
|
|
1135
|
+
case "paused_auto":
|
|
1136
|
+
return "paused (no success for 24 h)";
|
|
1137
|
+
case "paused_quota":
|
|
1138
|
+
return "paused (daily allowance exhausted)";
|
|
1139
|
+
case "quota_warning":
|
|
1140
|
+
return "80% of the daily allowance used";
|
|
1141
|
+
case "dropped":
|
|
1142
|
+
return "dropping records";
|
|
1143
|
+
case "verification_pending":
|
|
1144
|
+
return "still unverified";
|
|
1145
|
+
default: {
|
|
1146
|
+
const exhaustive = kind;
|
|
1147
|
+
throw new Error(`unhandled log-drain notice kind: ${String(exhaustive)}`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
function logDrainNoticeDigestCopy(payload) {
|
|
1152
|
+
const entries = [
|
|
1153
|
+
...payload.entries ?? []
|
|
1154
|
+
].sort((a, b) => a.at < b.at ? -1 : a.at > b.at ? 1 : 0).slice(0, LOG_DRAIN_DIGEST_MAX_ENTRIES);
|
|
1155
|
+
const drains = new Set(entries.map((entry) => entry.drainId));
|
|
1156
|
+
const noun = `${entries.length} notice${entries.length === 1 ? "" : "s"}`;
|
|
1157
|
+
const across = `${drains.size} drain${drains.size === 1 ? "" : "s"}`;
|
|
1158
|
+
const lines = entries.map((entry) => `${entry.drainName || entry.drainId} \u2014 ${logDrainNoticeLabel(entry.kind)}`);
|
|
1159
|
+
return {
|
|
1160
|
+
title: "Log drains \u2014 daily summary",
|
|
1161
|
+
subject: `Log drains \u2014 ${noun} in the last day`,
|
|
1162
|
+
previewLine: `${noun} across ${across}`,
|
|
1163
|
+
summary: `${noun} across ${across} in the last day: ${lines.join("; ")}.`,
|
|
1164
|
+
status: "failed",
|
|
1165
|
+
priority: "normal"
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
function finiteNonNegative(value3) {
|
|
1169
|
+
return typeof value3 === "number" && Number.isFinite(value3) && value3 >= 0 ? value3 : void 0;
|
|
1170
|
+
}
|
|
1171
|
+
function mergeLimits(base, stored) {
|
|
1172
|
+
const patch = stored ?? {};
|
|
1173
|
+
return {
|
|
1174
|
+
eventsPerDay: finiteNonNegative(patch.eventsPerDay) ?? base.eventsPerDay,
|
|
1175
|
+
bytesPerDay: finiteNonNegative(patch.bytesPerDay) ?? base.bytesPerDay
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
function mergeCard(base, stored) {
|
|
1179
|
+
const patch = stored ?? {};
|
|
1180
|
+
return {
|
|
1181
|
+
includedEventsPerMonth: finiteNonNegative(patch.includedEventsPerMonth) ?? base.includedEventsPerMonth,
|
|
1182
|
+
includedBytesPerMonth: finiteNonNegative(patch.includedBytesPerMonth) ?? base.includedBytesPerMonth,
|
|
1183
|
+
usdPerMillionEvents: finiteNonNegative(patch.usdPerMillionEvents) ?? base.usdPerMillionEvents,
|
|
1184
|
+
usdPerGiB: finiteNonNegative(patch.usdPerGiB) ?? base.usdPerGiB
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
function resolveStoredLogDrainPlanConfig(stored) {
|
|
1188
|
+
const values = stored;
|
|
1189
|
+
if (!values || typeof values.version !== "number" || !Number.isFinite(values.version)) {
|
|
1190
|
+
return DEFAULT_LOG_DRAIN_PLAN_CONFIG;
|
|
1191
|
+
}
|
|
1192
|
+
const tiers = {};
|
|
1193
|
+
const pricing = {};
|
|
1194
|
+
for (const tier of TIERS) {
|
|
1195
|
+
tiers[tier] = mergeLimits(DEFAULT_LOG_DRAIN_PLAN_CONFIG.tiers[tier], values.tiers?.[tier]);
|
|
1196
|
+
pricing[tier] = mergeCard(DEFAULT_LOG_DRAIN_PLAN_CONFIG.pricing[tier], values.pricing?.[tier]);
|
|
1197
|
+
}
|
|
1198
|
+
const orgs = {};
|
|
1199
|
+
for (const [orgId, override] of Object.entries(values.orgs ?? {})) {
|
|
1200
|
+
if (!orgId || !override || typeof override !== "object") continue;
|
|
1201
|
+
const row = {};
|
|
1202
|
+
if (override.tier && TIERS.includes(override.tier)) row.tier = override.tier;
|
|
1203
|
+
const events = finiteNonNegative(override.eventsPerDay);
|
|
1204
|
+
const bytes = finiteNonNegative(override.bytesPerDay);
|
|
1205
|
+
if (events !== void 0) row.eventsPerDay = events;
|
|
1206
|
+
if (bytes !== void 0) row.bytesPerDay = bytes;
|
|
1207
|
+
if (override.pricing && typeof override.pricing === "object") row.pricing = {
|
|
1208
|
+
...override.pricing
|
|
1209
|
+
};
|
|
1210
|
+
if (Object.keys(row).length) orgs[orgId] = row;
|
|
1211
|
+
}
|
|
1212
|
+
return {
|
|
1213
|
+
version: values.version,
|
|
1214
|
+
tiers,
|
|
1215
|
+
pricing,
|
|
1216
|
+
...Object.keys(orgs).length ? {
|
|
1217
|
+
orgs
|
|
1218
|
+
} : {}
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
function logDrainPlanTierOverride(config, orgId) {
|
|
1222
|
+
return orgId ? config.orgs?.[orgId]?.tier : void 0;
|
|
1223
|
+
}
|
|
1224
|
+
function logDrainQuotaLimitsFor(config, orgId, tier) {
|
|
1225
|
+
const base = config.tiers[tier] ?? config.tiers.team ?? LOG_DRAIN_QUOTAS.team;
|
|
1226
|
+
const override = orgId ? config.orgs?.[orgId] : void 0;
|
|
1227
|
+
if (!override) return {
|
|
1228
|
+
...base
|
|
1229
|
+
};
|
|
1230
|
+
return {
|
|
1231
|
+
eventsPerDay: override.eventsPerDay ?? base.eventsPerDay,
|
|
1232
|
+
bytesPerDay: override.bytesPerDay ?? base.bytesPerDay
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
function logDrainPriceCardFor(config, orgId, tier) {
|
|
1236
|
+
const base = config.pricing[tier] ?? config.pricing.team ?? DEFAULT_LOG_DRAIN_PLAN_CONFIG.pricing.team;
|
|
1237
|
+
const override = orgId ? config.orgs?.[orgId]?.pricing : void 0;
|
|
1238
|
+
return override ? mergeCard(base, override) : {
|
|
1239
|
+
...base
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
function priceDrainUsage(totals, card, tier) {
|
|
1243
|
+
const billableRecords = Math.max(0, Math.floor(finiteNonNegative(totals?.billableRecords) ?? 0));
|
|
1244
|
+
const billableBytes = Math.max(0, Math.floor(finiteNonNegative(totals?.billableBytes) ?? 0));
|
|
1245
|
+
const includedEvents = card.includedEventsPerMonth;
|
|
1246
|
+
const includedBytes = card.includedBytesPerMonth;
|
|
1247
|
+
const overageEvents = Math.max(0, billableRecords - includedEvents);
|
|
1248
|
+
const overageBytes = Math.max(0, billableBytes - includedBytes);
|
|
1249
|
+
const eventsUsd = overageEvents / 1e6 * card.usdPerMillionEvents;
|
|
1250
|
+
const bytesUsd = overageBytes / LOG_DRAIN_BYTES_PER_GIB * card.usdPerGiB;
|
|
1251
|
+
const unpriced = card.usdPerMillionEvents === 0 && card.usdPerGiB === 0;
|
|
1252
|
+
const round = /* @__PURE__ */ __name2((usd) => Math.round(usd * 100) / 100, "round");
|
|
1253
|
+
return {
|
|
1254
|
+
lineItem: LOG_DRAIN_USAGE_LINE_ITEM,
|
|
1255
|
+
tier,
|
|
1256
|
+
billableRecords,
|
|
1257
|
+
billableBytes,
|
|
1258
|
+
includedEvents,
|
|
1259
|
+
includedBytes,
|
|
1260
|
+
overageEvents,
|
|
1261
|
+
overageBytes,
|
|
1262
|
+
eventsUsd: round(eventsUsd),
|
|
1263
|
+
bytesUsd: round(bytesUsd),
|
|
1264
|
+
usd: round(Math.max(eventsUsd, bytesUsd)),
|
|
1265
|
+
unpriced
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
643
1268
|
function encodeLogCursor(c) {
|
|
644
1269
|
return Buffer.from(JSON.stringify({
|
|
645
1270
|
t: c.t,
|
|
@@ -657,12 +1282,12 @@ function decodeLogCursor(raw) {
|
|
|
657
1282
|
return null;
|
|
658
1283
|
}
|
|
659
1284
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
660
|
-
const { t, id } = parsed;
|
|
1285
|
+
const { t, id: id2 } = parsed;
|
|
661
1286
|
if (typeof t !== "number" || !Number.isSafeInteger(t) || t < 0) return null;
|
|
662
|
-
if (typeof
|
|
1287
|
+
if (typeof id2 !== "string" || !id2 || id2.length > LOG_CURSOR_MAX_ID_LENGTH) return null;
|
|
663
1288
|
return {
|
|
664
1289
|
t,
|
|
665
|
-
id
|
|
1290
|
+
id: id2
|
|
666
1291
|
};
|
|
667
1292
|
}
|
|
668
1293
|
function parseLogTimeBound(raw, now = /* @__PURE__ */ new Date()) {
|
|
@@ -900,62 +1525,62 @@ function isKnownProfile(profiles, profileId) {
|
|
|
900
1525
|
function hasCapability(profiles, profileId, required) {
|
|
901
1526
|
return capabilitiesFor(profiles, profileId).includes(required);
|
|
902
1527
|
}
|
|
903
|
-
function workflowJobId(
|
|
904
|
-
switch (
|
|
1528
|
+
function workflowJobId(id2) {
|
|
1529
|
+
switch (id2.kind) {
|
|
905
1530
|
case "start":
|
|
906
|
-
return `wft_${
|
|
1531
|
+
return `wft_${id2.runId}_0`;
|
|
907
1532
|
case "start-redrive":
|
|
908
|
-
return `wft_${
|
|
1533
|
+
return `wft_${id2.runId}_start_r${id2.now}`;
|
|
909
1534
|
case "tick":
|
|
910
|
-
return `wft_${
|
|
1535
|
+
return `wft_${id2.runId}_${id2.seq}`;
|
|
911
1536
|
case "timer":
|
|
912
|
-
return `wft_${
|
|
1537
|
+
return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}`;
|
|
913
1538
|
case "timer-remainder":
|
|
914
|
-
return `wft_${
|
|
1539
|
+
return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_r${id2.now}`;
|
|
915
1540
|
case "timer-deferral":
|
|
916
|
-
return `wft_${
|
|
1541
|
+
return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_d${id2.now}`;
|
|
917
1542
|
case "timer-sibling":
|
|
918
|
-
return `wft_${
|
|
1543
|
+
return `wft_${id2.runId}_timer_${id2.stepId}_${id2.attempt}_w${id2.now}`;
|
|
919
1544
|
case "retry":
|
|
920
|
-
return `wft_${
|
|
1545
|
+
return `wft_${id2.runId}_retry_${id2.stepId}_${id2.attempt}`;
|
|
921
1546
|
case "respawn":
|
|
922
|
-
return `wft_${
|
|
1547
|
+
return `wft_${id2.runId}_respawn_${id2.stepId}_${id2.attempt}_s${id2.segment}_r${id2.now}`;
|
|
923
1548
|
case "redrive":
|
|
924
|
-
return `wft_${
|
|
1549
|
+
return `wft_${id2.runId}_redrive_${id2.stepId}_${id2.attempt}_r${id2.now}`;
|
|
925
1550
|
case "redispatch":
|
|
926
|
-
return `wft_${
|
|
1551
|
+
return `wft_${id2.runId}_redispatch_${id2.stepId}_${id2.attempt}_x${id2.executionId ?? "none"}_r${id2.now}`;
|
|
927
1552
|
case "expiry":
|
|
928
|
-
return `wft_${
|
|
1553
|
+
return `wft_${id2.runId}_expire_${id2.stepId}_${id2.attempt}_t${id2.suspendedAt}${id2.hop > 0 ? `_h${id2.hop}` : ""}`;
|
|
929
1554
|
case "step-terminal":
|
|
930
|
-
return `wft_${
|
|
1555
|
+
return `wft_${id2.runId}_term_${id2.stepId}_${id2.attempt}_r${id2.now}`;
|
|
931
1556
|
case "handback":
|
|
932
|
-
return `wft_${
|
|
1557
|
+
return `wft_${id2.runId}_handback_${id2.stepId}_${id2.attempt}_${id2.now}`;
|
|
933
1558
|
case "foreach-rate":
|
|
934
|
-
return `wft_${
|
|
1559
|
+
return `wft_${id2.runId}_fe_${id2.stepId}_${id2.attempt}_${id2.bucket}`;
|
|
935
1560
|
case "budget-expiry":
|
|
936
|
-
return `wft_${
|
|
1561
|
+
return `wft_${id2.runId}_expiry_budget_r${id2.now}`;
|
|
937
1562
|
case "budget-resume":
|
|
938
|
-
return `wft_${
|
|
1563
|
+
return `wft_${id2.runId}_resume_budget_${id2.now}`;
|
|
939
1564
|
case "deadline":
|
|
940
|
-
return `wft_${
|
|
1565
|
+
return `wft_${id2.runId}_deadline_${id2.deadlineAt}`;
|
|
941
1566
|
case "deadline-remainder":
|
|
942
|
-
return `wft_${
|
|
1567
|
+
return `wft_${id2.runId}_deadline_${id2.deadlineAt}_r${id2.now}`;
|
|
943
1568
|
case "readmit":
|
|
944
|
-
return `wft_${
|
|
1569
|
+
return `wft_${id2.runId}_readmit_${id2.now}`;
|
|
945
1570
|
case "cancel":
|
|
946
|
-
return `wft_${
|
|
1571
|
+
return `wft_${id2.runId}_cancel`;
|
|
947
1572
|
case "reconcile":
|
|
948
|
-
return `wft_${
|
|
1573
|
+
return `wft_${id2.runId}_reconcile_${id2.now}`;
|
|
949
1574
|
case "replay":
|
|
950
|
-
return `wft_${
|
|
1575
|
+
return `wft_${id2.runId}_replay_g${id2.leaseGeneration}`;
|
|
951
1576
|
case "migration":
|
|
952
|
-
return `wfm_${
|
|
1577
|
+
return `wfm_${id2.migrationId}`;
|
|
953
1578
|
default:
|
|
954
|
-
return assertNever(
|
|
1579
|
+
return assertNever(id2);
|
|
955
1580
|
}
|
|
956
1581
|
}
|
|
957
|
-
function assertNever(
|
|
958
|
-
throw new Error(`workflowJobId: unknown wake kind ${JSON.stringify(
|
|
1582
|
+
function assertNever(id2) {
|
|
1583
|
+
throw new Error(`workflowJobId: unknown wake kind ${JSON.stringify(id2)}`);
|
|
959
1584
|
}
|
|
960
1585
|
function agentStepJobId(msg) {
|
|
961
1586
|
return `${msg.runId}_${msg.stepId}_${msg.attempt}_x${msg.executionId}`;
|
|
@@ -993,11 +1618,11 @@ function isArchiveWindowTooOld(run, retentionDays, now = Date.now(), marginDays
|
|
|
993
1618
|
function workflowOrgPurgingKey(orgId) {
|
|
994
1619
|
return `wf:org:${orgId}:purging`;
|
|
995
1620
|
}
|
|
996
|
-
function isCloudTaskRunId(
|
|
997
|
-
return
|
|
1621
|
+
function isCloudTaskRunId(id2) {
|
|
1622
|
+
return id2.startsWith(CLOUD_TASK_RUN_ID_PREFIX);
|
|
998
1623
|
}
|
|
999
|
-
function isScheduledWorkflowRunId(
|
|
1000
|
-
return
|
|
1624
|
+
function isScheduledWorkflowRunId(id2) {
|
|
1625
|
+
return id2.startsWith(WORKFLOW_SCHEDULED_RUN_ID_PREFIX);
|
|
1001
1626
|
}
|
|
1002
1627
|
function scheduledWorkflowRunId(jobId, scheduledTime) {
|
|
1003
1628
|
const key = typeof scheduledTime === "number" ? String(scheduledTime) : scheduledTimeKey(scheduledTime);
|
|
@@ -1358,7 +1983,13 @@ function effectiveAgentFeatures(base, override, rule) {
|
|
|
1358
1983
|
if (rule === "wholesale") return override || base || void 0;
|
|
1359
1984
|
return effectiveAgentFeatureRows(base, override).rows;
|
|
1360
1985
|
}
|
|
1361
|
-
|
|
1986
|
+
function parseOnboardingFlow(value3) {
|
|
1987
|
+
return onboardingFlowSchema.parse(value3);
|
|
1988
|
+
}
|
|
1989
|
+
function parsePublishedOnboardingResponse(value3) {
|
|
1990
|
+
return getPublishedOnboardingResponseSchema.parse(value3);
|
|
1991
|
+
}
|
|
1992
|
+
var __defProp2, __name2, PLUMBING_THREAD_CHANNELS, CHANNEL_CONVERSATION_CHANNELS, HIDDEN_THREAD_CHANNELS, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, 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, LOG_FIELDS_MAX_KEYS, LOG_FIELD_MAX_VALUE_BYTES, LOG_FIELDS_MAX_BYTES, LOG_FIELD_KEY_PATTERN, LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS, LOG_FIELDS_CLAMPED_KEY, LOG_FIELD_ARRAY_COUNT_SUFFIX, LuaLogFieldsError, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, 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_MODEL_CLASSES, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, 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, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, AGENT_LOG_FIELDS_MAX_WIRE_KEYS, LOG_DRAIN_TYPES_PHASE1, LOG_DRAIN_TYPES_PHASE2, LOG_DRAIN_TYPES_IMPLEMENTED, LOG_DRAIN_SOURCES, LOG_DRAIN_MAX_PER_ORG, LOG_DRAIN_MAX_PER_ORG_ENTERPRISE, LOG_DRAIN_DATADOG_SITES, LOG_DRAIN_NEWRELIC_SITES, LOG_DRAIN_ENDPOINT_TEMPLATES, LOG_DRAIN_PRESET_SITES, LOG_DRAIN_BUCKET_NAME_PATTERN, LOG_DRAIN_BUCKET_HOST_PATTERNS, LOG_DRAIN_PRESET_HOST_SUFFIXES, DRAIN_CONTENT_ACK_ERROR_CODE, DRAIN_CONTENT_ACK_FIELD, DrainContentAckRequiredError, LOG_DRAIN_PRESET_PATHS, PRESET_SEGMENT_RE, LOG_DRAIN_QUOTAS, LOG_DRAIN_QUOTA_WARN_RATIO, LOG_DRAIN_QUOTA_DROP_DEBUG_RATIO, LOG_DRAIN_QUOTA_DROP_INFO_RATIO, LOG_DRAIN_QUOTA_PAUSE_RATIO, LOG_EXPORT_SOURCES, LOG_EXPORT_MAX_WINDOW_DAYS, LOG_EXPORT_MAX_WINDOW_MS, LOG_EXPORT_URL_TTL_SECONDS, LOG_EXPORT_FILE_RETENTION_DAYS, LOG_EXPORT_FILE_RETENTION_MS, LOG_EXPORT_PART_MAX_BYTES, LOG_DRAIN_NOTICE_RATE_LIMIT_MS, LOG_DRAIN_VERIFICATION_STALE_MS, LOG_DRAIN_DIGEST_INTERVAL_MS, LOG_DRAIN_DIGEST_MAX_ENTRIES, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS, LOG_DRAIN_USAGE_LINE_ITEM, LOG_DRAIN_BYTES_PER_GIB, DEFAULT_LOG_DRAIN_PLAN_CONFIG, TIERS, LOG_CURSOR_MAX_LENGTH, LOG_CURSOR_MAX_ID_LENGTH, LOG_RELATIVE_TIME_PATTERN, LOG_ISO_TIME_PATTERN, RELATIVE_UNIT_MS, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, SESSION_AUTH_TIME_MAX_S, 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, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, 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_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, 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_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_JOB_MODEL_SOURCE_LABELS, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, WORKFLOW_GOAL_JUDGE_SELF, 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, DEFAULT_ON_AGENT_FEATURES, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES, ONBOARDING_FLOW_KEY, ONBOARDING_SCHEMA_VERSION, id, copy, onboardingHeadingSchema, onboardingRichTextInlineSchema, onboardingRichTextSchema, onboardingDestinationSchema, onboardingArtworkSchema, onboardingAnswerSchema, onboardingQuestionSchema, onboardingTemplateSectionSchema, onboardingTemplateContentSchema, onboardingUnavailableOutcomeSchema, onboardingFlowSchema, onboardingActorSchema, onboardingEditorSchema, onboardingPublicationSummarySchema, onboardingValidationIssueSchema, onboardingValidationResponseSchema, onboardingAssetSchema, onboardingPublicAssetSchema, getOnboardingConfigResponseSchema, saveOnboardingDraftRequestSchema, validateOnboardingRequestSchema, publishOnboardingRequestSchema, rollbackOnboardingRequestSchema, onboardingTemplateCatalogItemSchema, getPublishedOnboardingResponseSchema;
|
|
1362
1993
|
var init_dist = __esm({
|
|
1363
1994
|
"../shared-types/dist/index.mjs"() {
|
|
1364
1995
|
"use strict";
|
|
@@ -1686,6 +2317,50 @@ var init_dist = __esm({
|
|
|
1686
2317
|
}
|
|
1687
2318
|
];
|
|
1688
2319
|
BROWSER_COMMAND_NAMES = BROWSER_COMMANDS.map((c) => c.name);
|
|
2320
|
+
LOG_FIELDS_MAX_KEYS = 32;
|
|
2321
|
+
LOG_FIELD_MAX_VALUE_BYTES = 1024;
|
|
2322
|
+
LOG_FIELDS_MAX_BYTES = 8192;
|
|
2323
|
+
LOG_FIELD_KEY_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
|
|
2324
|
+
LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS = Object.freeze([
|
|
2325
|
+
/^api_[0-9a-f]{24,}$/,
|
|
2326
|
+
/^gh[pousr]_[a-z0-9]{36}$/,
|
|
2327
|
+
/^(?:sk|rk|pk)_(?:live|test)_[a-z0-9]{16,}$/,
|
|
2328
|
+
/^lua_hc_[a-z0-9]{20,}/,
|
|
2329
|
+
/^lua_sk_[a-z0-9]{20,}/
|
|
2330
|
+
]);
|
|
2331
|
+
LOG_FIELDS_CLAMPED_KEY = "lua_fields_clamped";
|
|
2332
|
+
LOG_FIELD_ARRAY_COUNT_SUFFIX = ".count";
|
|
2333
|
+
LuaLogFieldsError = class _LuaLogFieldsError extends Error {
|
|
2334
|
+
static {
|
|
2335
|
+
__name(this, "_LuaLogFieldsError");
|
|
2336
|
+
}
|
|
2337
|
+
static {
|
|
2338
|
+
__name2(this, "LuaLogFieldsError");
|
|
2339
|
+
}
|
|
2340
|
+
constructor(message) {
|
|
2341
|
+
super(message);
|
|
2342
|
+
this.name = "LuaLogFieldsError";
|
|
2343
|
+
Object.setPrototypeOf(this, _LuaLogFieldsError.prototype);
|
|
2344
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
__name(utf8WidthAt, "utf8WidthAt");
|
|
2347
|
+
__name2(utf8WidthAt, "utf8WidthAt");
|
|
2348
|
+
__name(utf8ByteLength, "utf8ByteLength");
|
|
2349
|
+
__name2(utf8ByteLength, "utf8ByteLength");
|
|
2350
|
+
__name(clampUtf8, "clampUtf8");
|
|
2351
|
+
__name2(clampUtf8, "clampUtf8");
|
|
2352
|
+
__name(mapBytes, "mapBytes");
|
|
2353
|
+
__name2(mapBytes, "mapBytes");
|
|
2354
|
+
__name(withValueCap, "withValueCap");
|
|
2355
|
+
__name2(withValueCap, "withValueCap");
|
|
2356
|
+
__name(describeValue, "describeValue");
|
|
2357
|
+
__name2(describeValue, "describeValue");
|
|
2358
|
+
__name(assertValidLogFieldKey, "assertValidLogFieldKey");
|
|
2359
|
+
__name2(assertValidLogFieldKey, "assertValidLogFieldKey");
|
|
2360
|
+
__name(normalizeLogFields, "normalizeLogFields");
|
|
2361
|
+
__name2(normalizeLogFields, "normalizeLogFields");
|
|
2362
|
+
__name(clampLogFields, "clampLogFields");
|
|
2363
|
+
__name2(clampLogFields, "clampLogFields");
|
|
1689
2364
|
DESKTOP_FILE_COMMANDS = [
|
|
1690
2365
|
"files_roots",
|
|
1691
2366
|
"files_stat",
|
|
@@ -2030,6 +2705,37 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2030
2705
|
"workflow-script",
|
|
2031
2706
|
"workflow"
|
|
2032
2707
|
];
|
|
2708
|
+
AGENT_LOG_FIELDS_MAX_WIRE_KEYS = LOG_FIELDS_MAX_KEYS + 1;
|
|
2709
|
+
__name(utf8Bytes, "utf8Bytes");
|
|
2710
|
+
__name2(utf8Bytes, "utf8Bytes");
|
|
2711
|
+
__name(isPlainFieldKey, "isPlainFieldKey");
|
|
2712
|
+
__name2(isPlainFieldKey, "isPlainFieldKey");
|
|
2713
|
+
__name(describeAgentLogFieldsViolation, "describeAgentLogFieldsViolation");
|
|
2714
|
+
__name2(describeAgentLogFieldsViolation, "describeAgentLogFieldsViolation");
|
|
2715
|
+
__name(isAgentLogFields, "isAgentLogFields");
|
|
2716
|
+
__name2(isAgentLogFields, "isAgentLogFields");
|
|
2717
|
+
LOG_DRAIN_TYPES_PHASE1 = [
|
|
2718
|
+
"http",
|
|
2719
|
+
"otlp",
|
|
2720
|
+
"datadog",
|
|
2721
|
+
"betterstack"
|
|
2722
|
+
];
|
|
2723
|
+
LOG_DRAIN_TYPES_PHASE2 = [
|
|
2724
|
+
"splunk",
|
|
2725
|
+
"loki",
|
|
2726
|
+
"axiom",
|
|
2727
|
+
"newrelic",
|
|
2728
|
+
"sumologic"
|
|
2729
|
+
];
|
|
2730
|
+
LOG_DRAIN_TYPES_IMPLEMENTED = [
|
|
2731
|
+
...LOG_DRAIN_TYPES_PHASE1,
|
|
2732
|
+
...LOG_DRAIN_TYPES_PHASE2,
|
|
2733
|
+
// RECONCILE-4 (W4-4). `s3` is implemented (H4 / PRO-1887) but is NOT in
|
|
2734
|
+
// `LOG_DRAIN_TYPES_PHASE2`, because its own flag opens it and `*` must not. It
|
|
2735
|
+
// belongs here all the same: this list is what a CLIENT may offer, and the server
|
|
2736
|
+
// remains the authority that answers 422 with the live list.
|
|
2737
|
+
"s3"
|
|
2738
|
+
];
|
|
2033
2739
|
LOG_DRAIN_SOURCES = [
|
|
2034
2740
|
...AGENT_LOG_SOURCES,
|
|
2035
2741
|
"execution",
|
|
@@ -2038,17 +2744,123 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2038
2744
|
"trigger-execution",
|
|
2039
2745
|
"job-execution",
|
|
2040
2746
|
"workflow-run",
|
|
2041
|
-
"workflow-audit"
|
|
2747
|
+
"workflow-audit",
|
|
2748
|
+
// PRO-1884 (H2). Appended AFTER 'workflow-audit' so the enum stays additive and
|
|
2749
|
+
// no existing member changes position.
|
|
2750
|
+
"voice-call"
|
|
2042
2751
|
];
|
|
2043
2752
|
LOG_DRAIN_MAX_PER_ORG = 5;
|
|
2044
2753
|
LOG_DRAIN_MAX_PER_ORG_ENTERPRISE = 10;
|
|
2045
2754
|
__name(maxDrainsForTier, "maxDrainsForTier");
|
|
2046
2755
|
__name2(maxDrainsForTier, "maxDrainsForTier");
|
|
2756
|
+
LOG_DRAIN_DATADOG_SITES = [
|
|
2757
|
+
"datadoghq.com",
|
|
2758
|
+
"datadoghq.eu",
|
|
2759
|
+
"us3.datadoghq.com",
|
|
2760
|
+
"us5.datadoghq.com",
|
|
2761
|
+
"ap1.datadoghq.com",
|
|
2762
|
+
"ddog-gov.com"
|
|
2763
|
+
];
|
|
2764
|
+
LOG_DRAIN_NEWRELIC_SITES = [
|
|
2765
|
+
"log-api.newrelic.com",
|
|
2766
|
+
"log-api.eu.newrelic.com",
|
|
2767
|
+
"log-api.jp.newrelic.com"
|
|
2768
|
+
];
|
|
2047
2769
|
LOG_DRAIN_ENDPOINT_TEMPLATES = {
|
|
2048
|
-
datadog: "https://http-intake.logs.{site}/api/v2/logs"
|
|
2770
|
+
datadog: "https://http-intake.logs.{site}/api/v2/logs",
|
|
2771
|
+
newrelic: "https://{site}/log/v1"
|
|
2772
|
+
};
|
|
2773
|
+
LOG_DRAIN_PRESET_SITES = {
|
|
2774
|
+
datadog: LOG_DRAIN_DATADOG_SITES,
|
|
2775
|
+
newrelic: LOG_DRAIN_NEWRELIC_SITES
|
|
2049
2776
|
};
|
|
2050
2777
|
__name(resolvePresetEndpoint, "resolvePresetEndpoint");
|
|
2051
2778
|
__name2(resolvePresetEndpoint, "resolvePresetEndpoint");
|
|
2779
|
+
LOG_DRAIN_BUCKET_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
|
|
2780
|
+
LOG_DRAIN_BUCKET_HOST_PATTERNS = Object.freeze({
|
|
2781
|
+
aws: [
|
|
2782
|
+
// virtual-host style, regional and legacy global
|
|
2783
|
+
/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]\.s3(\.dualstack)?(\.[a-z0-9-]+)?\.amazonaws\.com$/,
|
|
2784
|
+
// path style
|
|
2785
|
+
/^s3(\.dualstack)?(\.[a-z0-9-]+)?\.amazonaws\.com$/
|
|
2786
|
+
],
|
|
2787
|
+
r2: [
|
|
2788
|
+
/^[a-f0-9]{32}\.r2\.cloudflarestorage\.com$/
|
|
2789
|
+
],
|
|
2790
|
+
gcs: [
|
|
2791
|
+
/^storage\.googleapis\.com$/
|
|
2792
|
+
]
|
|
2793
|
+
});
|
|
2794
|
+
__name(isLogDrainBucketHostAllowed, "isLogDrainBucketHostAllowed");
|
|
2795
|
+
__name2(isLogDrainBucketHostAllowed, "isLogDrainBucketHostAllowed");
|
|
2796
|
+
__name(resolveDrainBucketEndpoint, "resolveDrainBucketEndpoint");
|
|
2797
|
+
__name2(resolveDrainBucketEndpoint, "resolveDrainBucketEndpoint");
|
|
2798
|
+
__name(drainBucketUsesPathStyle, "drainBucketUsesPathStyle");
|
|
2799
|
+
__name2(drainBucketUsesPathStyle, "drainBucketUsesPathStyle");
|
|
2800
|
+
__name(presetIntakeHosts, "presetIntakeHosts");
|
|
2801
|
+
__name2(presetIntakeHosts, "presetIntakeHosts");
|
|
2802
|
+
LOG_DRAIN_PRESET_HOST_SUFFIXES = {
|
|
2803
|
+
axiom: [
|
|
2804
|
+
".axiom.co"
|
|
2805
|
+
],
|
|
2806
|
+
sumologic: [
|
|
2807
|
+
".sumologic.com"
|
|
2808
|
+
]
|
|
2809
|
+
};
|
|
2810
|
+
__name(presetHostAllowlist, "presetHostAllowlist");
|
|
2811
|
+
__name2(presetHostAllowlist, "presetHostAllowlist");
|
|
2812
|
+
__name(drainHostAllowlistAllows, "drainHostAllowlistAllows");
|
|
2813
|
+
__name2(drainHostAllowlistAllows, "drainHostAllowlistAllows");
|
|
2814
|
+
__name(drainDestinationIsVendorPinned, "drainDestinationIsVendorPinned");
|
|
2815
|
+
__name2(drainDestinationIsVendorPinned, "drainDestinationIsVendorPinned");
|
|
2816
|
+
__name(drainVerificationOwnership, "drainVerificationOwnership");
|
|
2817
|
+
__name2(drainVerificationOwnership, "drainVerificationOwnership");
|
|
2818
|
+
__name(drainOwnershipOrDefault, "drainOwnershipOrDefault");
|
|
2819
|
+
__name2(drainOwnershipOrDefault, "drainOwnershipOrDefault");
|
|
2820
|
+
DRAIN_CONTENT_ACK_ERROR_CODE = "DRAIN_CONTENT_ACK_REQUIRED";
|
|
2821
|
+
DRAIN_CONTENT_ACK_FIELD = "includeContentAck";
|
|
2822
|
+
DrainContentAckRequiredError = class extends Error {
|
|
2823
|
+
static {
|
|
2824
|
+
__name(this, "DrainContentAckRequiredError");
|
|
2825
|
+
}
|
|
2826
|
+
static {
|
|
2827
|
+
__name2(this, "DrainContentAckRequiredError");
|
|
2828
|
+
}
|
|
2829
|
+
code = DRAIN_CONTENT_ACK_ERROR_CODE;
|
|
2830
|
+
field = DRAIN_CONTENT_ACK_FIELD;
|
|
2831
|
+
constructor() {
|
|
2832
|
+
super("includeContent ships end-user message content to a third party; set includeContentAck: true to confirm.");
|
|
2833
|
+
this.name = "DrainContentAckRequiredError";
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
__name(assertDrainContentAck, "assertDrainContentAck");
|
|
2837
|
+
__name2(assertDrainContentAck, "assertDrainContentAck");
|
|
2838
|
+
LOG_DRAIN_PRESET_PATHS = {
|
|
2839
|
+
// https://docs.splunk.com/Documentation/Splunk/latest/Data/HECExamples
|
|
2840
|
+
splunk: {
|
|
2841
|
+
path: "/services/collector/event"
|
|
2842
|
+
},
|
|
2843
|
+
// https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs
|
|
2844
|
+
loki: {
|
|
2845
|
+
path: "/loki/api/v1/push"
|
|
2846
|
+
},
|
|
2847
|
+
// https://axiom.co/docs/restapi/endpoints/ingestIntoDataset
|
|
2848
|
+
axiom: {
|
|
2849
|
+
path: "/v1/datasets",
|
|
2850
|
+
segment: "dataset",
|
|
2851
|
+
suffix: "/ingest"
|
|
2852
|
+
},
|
|
2853
|
+
// https://help.sumologic.com/docs/send-data/hosted-collectors/http-source/logs-metrics/upload-logs/
|
|
2854
|
+
sumologic: {
|
|
2855
|
+
path: "/receiver/v1/http",
|
|
2856
|
+
segment: "token"
|
|
2857
|
+
}
|
|
2858
|
+
};
|
|
2859
|
+
PRESET_SEGMENT_RE = /^[A-Za-z0-9._~%=+-]{1,512}$/;
|
|
2860
|
+
__name(composePresetEndpoint, "composePresetEndpoint");
|
|
2861
|
+
__name2(composePresetEndpoint, "composePresetEndpoint");
|
|
2862
|
+
__name(joinPresetEndpointToken, "joinPresetEndpointToken");
|
|
2863
|
+
__name2(joinPresetEndpointToken, "joinPresetEndpointToken");
|
|
2052
2864
|
LOG_DRAIN_QUOTAS = {
|
|
2053
2865
|
team: {
|
|
2054
2866
|
eventsPerDay: 1e6,
|
|
@@ -2081,6 +2893,100 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
2081
2893
|
__name2(logDrainQuotaWarned, "logDrainQuotaWarned");
|
|
2082
2894
|
__name(logDrainQuotaDroppedSeverities, "logDrainQuotaDroppedSeverities");
|
|
2083
2895
|
__name2(logDrainQuotaDroppedSeverities, "logDrainQuotaDroppedSeverities");
|
|
2896
|
+
LOG_EXPORT_SOURCES = [
|
|
2897
|
+
...AGENT_LOG_SOURCES,
|
|
2898
|
+
"execution"
|
|
2899
|
+
];
|
|
2900
|
+
LOG_EXPORT_MAX_WINDOW_DAYS = 31;
|
|
2901
|
+
LOG_EXPORT_MAX_WINDOW_MS = LOG_EXPORT_MAX_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
|
|
2902
|
+
LOG_EXPORT_URL_TTL_SECONDS = 24 * 60 * 60;
|
|
2903
|
+
LOG_EXPORT_FILE_RETENTION_DAYS = 7;
|
|
2904
|
+
LOG_EXPORT_FILE_RETENTION_MS = LOG_EXPORT_FILE_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
2905
|
+
LOG_EXPORT_PART_MAX_BYTES = 256 * 1024 * 1024;
|
|
2906
|
+
__name(isLogExportSource, "isLogExportSource");
|
|
2907
|
+
__name2(isLogExportSource, "isLogExportSource");
|
|
2908
|
+
LOG_DRAIN_NOTICE_RATE_LIMIT_MS = 60 * 6e4;
|
|
2909
|
+
LOG_DRAIN_VERIFICATION_STALE_MS = 24 * 60 * 6e4;
|
|
2910
|
+
LOG_DRAIN_DIGEST_INTERVAL_MS = 24 * 60 * 6e4;
|
|
2911
|
+
LOG_DRAIN_DIGEST_MAX_ENTRIES = 50;
|
|
2912
|
+
LOG_DRAIN_NOTICE_ERROR_MAX_CHARS = 200;
|
|
2913
|
+
__name(clamp, "clamp");
|
|
2914
|
+
__name2(clamp, "clamp");
|
|
2915
|
+
__name(numberOr, "numberOr");
|
|
2916
|
+
__name2(numberOr, "numberOr");
|
|
2917
|
+
__name(isoOr, "isoOr");
|
|
2918
|
+
__name2(isoOr, "isoOr");
|
|
2919
|
+
__name(logDrainNoticeView, "logDrainNoticeView");
|
|
2920
|
+
__name2(logDrainNoticeView, "logDrainNoticeView");
|
|
2921
|
+
__name(logDrainHealthCardPath, "logDrainHealthCardPath");
|
|
2922
|
+
__name2(logDrainHealthCardPath, "logDrainHealthCardPath");
|
|
2923
|
+
__name(percent, "percent");
|
|
2924
|
+
__name2(percent, "percent");
|
|
2925
|
+
__name(becauseClause, "becauseClause");
|
|
2926
|
+
__name2(becauseClause, "becauseClause");
|
|
2927
|
+
__name(logDrainNoticeCopy, "logDrainNoticeCopy");
|
|
2928
|
+
__name2(logDrainNoticeCopy, "logDrainNoticeCopy");
|
|
2929
|
+
__name(logDrainNoticeLabel, "logDrainNoticeLabel");
|
|
2930
|
+
__name2(logDrainNoticeLabel, "logDrainNoticeLabel");
|
|
2931
|
+
__name(logDrainNoticeDigestCopy, "logDrainNoticeDigestCopy");
|
|
2932
|
+
__name2(logDrainNoticeDigestCopy, "logDrainNoticeDigestCopy");
|
|
2933
|
+
LOG_DRAIN_USAGE_LINE_ITEM = "log_drain_events";
|
|
2934
|
+
LOG_DRAIN_BYTES_PER_GIB = 1024 ** 3;
|
|
2935
|
+
DEFAULT_LOG_DRAIN_PLAN_CONFIG = {
|
|
2936
|
+
version: 1,
|
|
2937
|
+
tiers: {
|
|
2938
|
+
team: {
|
|
2939
|
+
...LOG_DRAIN_QUOTAS.team
|
|
2940
|
+
},
|
|
2941
|
+
business: {
|
|
2942
|
+
...LOG_DRAIN_QUOTAS.business
|
|
2943
|
+
},
|
|
2944
|
+
enterprise: {
|
|
2945
|
+
...LOG_DRAIN_QUOTAS.enterprise
|
|
2946
|
+
}
|
|
2947
|
+
},
|
|
2948
|
+
pricing: {
|
|
2949
|
+
team: {
|
|
2950
|
+
includedEventsPerMonth: 0,
|
|
2951
|
+
includedBytesPerMonth: 0,
|
|
2952
|
+
usdPerMillionEvents: 0,
|
|
2953
|
+
usdPerGiB: 0
|
|
2954
|
+
},
|
|
2955
|
+
business: {
|
|
2956
|
+
includedEventsPerMonth: 0,
|
|
2957
|
+
includedBytesPerMonth: 0,
|
|
2958
|
+
usdPerMillionEvents: 0,
|
|
2959
|
+
usdPerGiB: 0
|
|
2960
|
+
},
|
|
2961
|
+
enterprise: {
|
|
2962
|
+
includedEventsPerMonth: 0,
|
|
2963
|
+
includedBytesPerMonth: 0,
|
|
2964
|
+
usdPerMillionEvents: 0,
|
|
2965
|
+
usdPerGiB: 0
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
};
|
|
2969
|
+
TIERS = [
|
|
2970
|
+
"team",
|
|
2971
|
+
"business",
|
|
2972
|
+
"enterprise"
|
|
2973
|
+
];
|
|
2974
|
+
__name(finiteNonNegative, "finiteNonNegative");
|
|
2975
|
+
__name2(finiteNonNegative, "finiteNonNegative");
|
|
2976
|
+
__name(mergeLimits, "mergeLimits");
|
|
2977
|
+
__name2(mergeLimits, "mergeLimits");
|
|
2978
|
+
__name(mergeCard, "mergeCard");
|
|
2979
|
+
__name2(mergeCard, "mergeCard");
|
|
2980
|
+
__name(resolveStoredLogDrainPlanConfig, "resolveStoredLogDrainPlanConfig");
|
|
2981
|
+
__name2(resolveStoredLogDrainPlanConfig, "resolveStoredLogDrainPlanConfig");
|
|
2982
|
+
__name(logDrainPlanTierOverride, "logDrainPlanTierOverride");
|
|
2983
|
+
__name2(logDrainPlanTierOverride, "logDrainPlanTierOverride");
|
|
2984
|
+
__name(logDrainQuotaLimitsFor, "logDrainQuotaLimitsFor");
|
|
2985
|
+
__name2(logDrainQuotaLimitsFor, "logDrainQuotaLimitsFor");
|
|
2986
|
+
__name(logDrainPriceCardFor, "logDrainPriceCardFor");
|
|
2987
|
+
__name2(logDrainPriceCardFor, "logDrainPriceCardFor");
|
|
2988
|
+
__name(priceDrainUsage, "priceDrainUsage");
|
|
2989
|
+
__name2(priceDrainUsage, "priceDrainUsage");
|
|
2084
2990
|
LOG_CURSOR_MAX_LENGTH = 512;
|
|
2085
2991
|
LOG_CURSOR_MAX_ID_LENGTH = 128;
|
|
2086
2992
|
LOG_RELATIVE_TIME_PATTERN = /^(\d{1,9})([smhd])$/;
|
|
@@ -3244,6 +4150,236 @@ listed here; never invent a target.`;
|
|
|
3244
4150
|
__name2(agentFeatureMergeRuleFromEnv, "agentFeatureMergeRuleFromEnv");
|
|
3245
4151
|
__name(effectiveAgentFeatures, "effectiveAgentFeatures");
|
|
3246
4152
|
__name2(effectiveAgentFeatures, "effectiveAgentFeatures");
|
|
4153
|
+
ONBOARDING_FLOW_KEY = "alpha-choose-meet";
|
|
4154
|
+
ONBOARDING_SCHEMA_VERSION = 1;
|
|
4155
|
+
id = z4.string().min(1).max(80).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/);
|
|
4156
|
+
copy = /* @__PURE__ */ __name2((max) => z4.string().max(max), "copy");
|
|
4157
|
+
onboardingHeadingSchema = z4.discriminatedUnion("kind", [
|
|
4158
|
+
z4.object({
|
|
4159
|
+
kind: z4.literal("plain"),
|
|
4160
|
+
text: copy(240)
|
|
4161
|
+
}).strict(),
|
|
4162
|
+
z4.object({
|
|
4163
|
+
kind: z4.literal("highlighted"),
|
|
4164
|
+
before: copy(240),
|
|
4165
|
+
highlight: copy(240),
|
|
4166
|
+
after: copy(240)
|
|
4167
|
+
}).strict()
|
|
4168
|
+
]);
|
|
4169
|
+
onboardingRichTextInlineSchema = z4.discriminatedUnion("kind", [
|
|
4170
|
+
z4.object({
|
|
4171
|
+
kind: z4.literal("text"),
|
|
4172
|
+
text: copy(2e3),
|
|
4173
|
+
marks: z4.array(z4.enum([
|
|
4174
|
+
"bold",
|
|
4175
|
+
"italic"
|
|
4176
|
+
])).max(2).refine((marks) => new Set(marks).size === marks.length, "Text marks must be unique").optional()
|
|
4177
|
+
}).strict(),
|
|
4178
|
+
z4.object({
|
|
4179
|
+
kind: z4.literal("lineBreak")
|
|
4180
|
+
}).strict()
|
|
4181
|
+
]);
|
|
4182
|
+
onboardingRichTextSchema = z4.object({
|
|
4183
|
+
blocks: z4.array(z4.object({
|
|
4184
|
+
kind: z4.literal("paragraph"),
|
|
4185
|
+
content: z4.array(onboardingRichTextInlineSchema).max(100)
|
|
4186
|
+
}).strict()).max(40)
|
|
4187
|
+
}).strict();
|
|
4188
|
+
onboardingDestinationSchema = z4.discriminatedUnion("kind", [
|
|
4189
|
+
z4.object({
|
|
4190
|
+
kind: z4.literal("question"),
|
|
4191
|
+
questionId: id
|
|
4192
|
+
}).strict(),
|
|
4193
|
+
z4.object({
|
|
4194
|
+
kind: z4.literal("template"),
|
|
4195
|
+
templateContentId: id
|
|
4196
|
+
}).strict(),
|
|
4197
|
+
z4.object({
|
|
4198
|
+
kind: z4.literal("unavailable"),
|
|
4199
|
+
unavailableId: id
|
|
4200
|
+
}).strict()
|
|
4201
|
+
]);
|
|
4202
|
+
onboardingArtworkSchema = z4.discriminatedUnion("kind", [
|
|
4203
|
+
z4.object({
|
|
4204
|
+
kind: z4.literal("builtinRing")
|
|
4205
|
+
}).strict(),
|
|
4206
|
+
z4.object({
|
|
4207
|
+
kind: z4.literal("uploaded"),
|
|
4208
|
+
assetId: id,
|
|
4209
|
+
accessibility: z4.discriminatedUnion("kind", [
|
|
4210
|
+
z4.object({
|
|
4211
|
+
kind: z4.literal("decorative")
|
|
4212
|
+
}).strict(),
|
|
4213
|
+
z4.object({
|
|
4214
|
+
kind: z4.literal("described"),
|
|
4215
|
+
altText: copy(500)
|
|
4216
|
+
}).strict()
|
|
4217
|
+
])
|
|
4218
|
+
}).strict()
|
|
4219
|
+
]);
|
|
4220
|
+
onboardingAnswerSchema = z4.object({
|
|
4221
|
+
id,
|
|
4222
|
+
label: copy(160),
|
|
4223
|
+
supportingText: copy(500).optional(),
|
|
4224
|
+
destination: onboardingDestinationSchema.nullable()
|
|
4225
|
+
}).strict();
|
|
4226
|
+
onboardingQuestionSchema = z4.object({
|
|
4227
|
+
id,
|
|
4228
|
+
heading: onboardingHeadingSchema,
|
|
4229
|
+
helperText: onboardingRichTextSchema.optional(),
|
|
4230
|
+
continueButtonLabel: copy(80),
|
|
4231
|
+
answers: z4.array(onboardingAnswerSchema).max(30)
|
|
4232
|
+
}).strict();
|
|
4233
|
+
onboardingTemplateSectionSchema = z4.object({
|
|
4234
|
+
id,
|
|
4235
|
+
label: copy(100),
|
|
4236
|
+
body: onboardingRichTextSchema
|
|
4237
|
+
}).strict();
|
|
4238
|
+
onboardingTemplateContentSchema = z4.object({
|
|
4239
|
+
id,
|
|
4240
|
+
templateId: copy(160),
|
|
4241
|
+
displayName: copy(100),
|
|
4242
|
+
eyebrow: copy(100).optional(),
|
|
4243
|
+
heading: onboardingHeadingSchema,
|
|
4244
|
+
description: onboardingRichTextSchema,
|
|
4245
|
+
badges: z4.array(copy(80)).max(12),
|
|
4246
|
+
sections: z4.array(onboardingTemplateSectionSchema).max(20),
|
|
4247
|
+
artwork: onboardingArtworkSchema,
|
|
4248
|
+
hireButtonLabel: copy(80),
|
|
4249
|
+
changeRoleButtonLabel: copy(80),
|
|
4250
|
+
nextStepText: onboardingRichTextSchema
|
|
4251
|
+
}).strict();
|
|
4252
|
+
onboardingUnavailableOutcomeSchema = z4.object({
|
|
4253
|
+
id,
|
|
4254
|
+
heading: onboardingHeadingSchema,
|
|
4255
|
+
explanation: onboardingRichTextSchema,
|
|
4256
|
+
backButtonLabel: copy(80),
|
|
4257
|
+
alternative: z4.object({
|
|
4258
|
+
templateContentId: id,
|
|
4259
|
+
introduction: onboardingRichTextSchema,
|
|
4260
|
+
buttonLabel: copy(80)
|
|
4261
|
+
}).strict().optional()
|
|
4262
|
+
}).strict();
|
|
4263
|
+
onboardingFlowSchema = z4.object({
|
|
4264
|
+
key: z4.literal(ONBOARDING_FLOW_KEY),
|
|
4265
|
+
schemaVersion: z4.literal(ONBOARDING_SCHEMA_VERSION),
|
|
4266
|
+
entryQuestionId: id.nullable(),
|
|
4267
|
+
questions: z4.array(onboardingQuestionSchema).max(100),
|
|
4268
|
+
templateContents: z4.array(onboardingTemplateContentSchema).max(100),
|
|
4269
|
+
unavailableOutcomes: z4.array(onboardingUnavailableOutcomeSchema).max(100)
|
|
4270
|
+
}).strict();
|
|
4271
|
+
onboardingActorSchema = z4.object({
|
|
4272
|
+
subjectId: z4.string(),
|
|
4273
|
+
email: z4.string().email()
|
|
4274
|
+
}).strict();
|
|
4275
|
+
onboardingEditorSchema = onboardingActorSchema.extend({
|
|
4276
|
+
editedAt: z4.string().datetime({
|
|
4277
|
+
offset: true
|
|
4278
|
+
})
|
|
4279
|
+
}).strict();
|
|
4280
|
+
onboardingPublicationSummarySchema = z4.object({
|
|
4281
|
+
publicationId: id,
|
|
4282
|
+
revision: z4.number().int().positive(),
|
|
4283
|
+
sourceDraftVersion: z4.number().int().nonnegative(),
|
|
4284
|
+
contentHash: z4.string().regex(/^[a-f0-9]{64}$/),
|
|
4285
|
+
publishedAt: z4.string().datetime({
|
|
4286
|
+
offset: true
|
|
4287
|
+
}),
|
|
4288
|
+
publishedBy: onboardingActorSchema,
|
|
4289
|
+
questionCount: z4.number().int().nonnegative(),
|
|
4290
|
+
templateCount: z4.number().int().nonnegative(),
|
|
4291
|
+
unavailableCount: z4.number().int().nonnegative()
|
|
4292
|
+
}).strict();
|
|
4293
|
+
onboardingValidationIssueSchema = z4.object({
|
|
4294
|
+
code: z4.string(),
|
|
4295
|
+
path: z4.string(),
|
|
4296
|
+
message: z4.string()
|
|
4297
|
+
}).strict();
|
|
4298
|
+
onboardingValidationResponseSchema = z4.discriminatedUnion("valid", [
|
|
4299
|
+
z4.object({
|
|
4300
|
+
valid: z4.literal(true),
|
|
4301
|
+
summary: z4.object({
|
|
4302
|
+
questionCount: z4.number().int().nonnegative(),
|
|
4303
|
+
templateCount: z4.number().int().nonnegative(),
|
|
4304
|
+
unavailableCount: z4.number().int().nonnegative()
|
|
4305
|
+
}).strict()
|
|
4306
|
+
}).strict(),
|
|
4307
|
+
z4.object({
|
|
4308
|
+
valid: z4.literal(false),
|
|
4309
|
+
issues: z4.array(onboardingValidationIssueSchema)
|
|
4310
|
+
}).strict()
|
|
4311
|
+
]);
|
|
4312
|
+
onboardingAssetSchema = z4.object({
|
|
4313
|
+
assetId: id,
|
|
4314
|
+
url: z4.string().url(),
|
|
4315
|
+
width: z4.number().int().positive(),
|
|
4316
|
+
height: z4.number().int().positive(),
|
|
4317
|
+
contentType: z4.enum([
|
|
4318
|
+
"image/png",
|
|
4319
|
+
"image/jpeg",
|
|
4320
|
+
"image/webp"
|
|
4321
|
+
]),
|
|
4322
|
+
bytes: z4.number().int().positive(),
|
|
4323
|
+
sha256: z4.string().regex(/^[a-f0-9]{64}$/),
|
|
4324
|
+
createdAt: z4.string().datetime({
|
|
4325
|
+
offset: true
|
|
4326
|
+
}),
|
|
4327
|
+
uploadedBy: onboardingActorSchema
|
|
4328
|
+
}).strict();
|
|
4329
|
+
onboardingPublicAssetSchema = onboardingAssetSchema.pick({
|
|
4330
|
+
assetId: true,
|
|
4331
|
+
url: true,
|
|
4332
|
+
width: true,
|
|
4333
|
+
height: true,
|
|
4334
|
+
contentType: true
|
|
4335
|
+
}).strict();
|
|
4336
|
+
getOnboardingConfigResponseSchema = z4.object({
|
|
4337
|
+
flowKey: z4.literal(ONBOARDING_FLOW_KEY),
|
|
4338
|
+
draftVersion: z4.number().int().nonnegative(),
|
|
4339
|
+
draft: onboardingFlowSchema,
|
|
4340
|
+
assets: z4.array(onboardingAssetSchema),
|
|
4341
|
+
lastEditor: onboardingEditorSchema.nullable(),
|
|
4342
|
+
activePublication: onboardingPublicationSummarySchema.nullable()
|
|
4343
|
+
}).strict();
|
|
4344
|
+
saveOnboardingDraftRequestSchema = z4.object({
|
|
4345
|
+
expectedDraftVersion: z4.number().int().nonnegative(),
|
|
4346
|
+
draft: onboardingFlowSchema
|
|
4347
|
+
}).strict();
|
|
4348
|
+
validateOnboardingRequestSchema = z4.object({
|
|
4349
|
+
draft: onboardingFlowSchema
|
|
4350
|
+
}).strict();
|
|
4351
|
+
publishOnboardingRequestSchema = z4.object({
|
|
4352
|
+
expectedDraftVersion: z4.number().int().nonnegative(),
|
|
4353
|
+
expectedActivePublicationId: id.nullable()
|
|
4354
|
+
}).strict();
|
|
4355
|
+
rollbackOnboardingRequestSchema = z4.object({
|
|
4356
|
+
publicationId: id,
|
|
4357
|
+
expectedActivePublicationId: id.nullable()
|
|
4358
|
+
}).strict();
|
|
4359
|
+
onboardingTemplateCatalogItemSchema = z4.object({
|
|
4360
|
+
templateId: z4.string(),
|
|
4361
|
+
name: z4.string(),
|
|
4362
|
+
description: z4.string().optional()
|
|
4363
|
+
}).strict();
|
|
4364
|
+
getPublishedOnboardingResponseSchema = z4.discriminatedUnion("status", [
|
|
4365
|
+
z4.object({
|
|
4366
|
+
status: z4.literal("available"),
|
|
4367
|
+
publicationId: id,
|
|
4368
|
+
revision: z4.number().int().positive(),
|
|
4369
|
+
contentHash: z4.string().regex(/^[a-f0-9]{64}$/),
|
|
4370
|
+
flow: onboardingFlowSchema,
|
|
4371
|
+
assets: z4.array(onboardingPublicAssetSchema)
|
|
4372
|
+
}).strict(),
|
|
4373
|
+
z4.object({
|
|
4374
|
+
status: z4.literal("unavailable"),
|
|
4375
|
+
reason: z4.literal("not_published"),
|
|
4376
|
+
message: z4.string()
|
|
4377
|
+
}).strict()
|
|
4378
|
+
]);
|
|
4379
|
+
__name(parseOnboardingFlow, "parseOnboardingFlow");
|
|
4380
|
+
__name2(parseOnboardingFlow, "parseOnboardingFlow");
|
|
4381
|
+
__name(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
|
|
4382
|
+
__name2(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
|
|
3247
4383
|
}
|
|
3248
4384
|
});
|
|
3249
4385
|
|
|
@@ -3251,9 +4387,9 @@ listed here; never invent a target.`;
|
|
|
3251
4387
|
function effectiveJobTools(jobTools, readOnly) {
|
|
3252
4388
|
const base = jobTools?.length ? jobTools : WORKFLOW_JOB_DEFAULT_TOOLS;
|
|
3253
4389
|
const out = [];
|
|
3254
|
-
for (const
|
|
3255
|
-
if (readOnly && WORKFLOW_JOB_READ_ONLY_DROPPED.includes(
|
|
3256
|
-
if (!out.includes(
|
|
4390
|
+
for (const id2 of base) {
|
|
4391
|
+
if (readOnly && WORKFLOW_JOB_READ_ONLY_DROPPED.includes(id2)) continue;
|
|
4392
|
+
if (!out.includes(id2)) out.push(id2);
|
|
3257
4393
|
}
|
|
3258
4394
|
return out;
|
|
3259
4395
|
}
|
|
@@ -3297,7 +4433,7 @@ var init_workflow_job_tools = __esm({
|
|
|
3297
4433
|
|
|
3298
4434
|
// ../workflow-graph/dist/index.mjs
|
|
3299
4435
|
import { createHash } from "crypto";
|
|
3300
|
-
import { z as
|
|
4436
|
+
import { z as z5 } from "zod";
|
|
3301
4437
|
import { z as z22 } from "zod";
|
|
3302
4438
|
import { createHash as createHash2 } from "crypto";
|
|
3303
4439
|
function isMapConfigObject(v) {
|
|
@@ -3424,9 +4560,9 @@ function malformedMapMembers(cfg) {
|
|
|
3424
4560
|
}
|
|
3425
4561
|
return out;
|
|
3426
4562
|
}
|
|
3427
|
-
function mapMemberMalformedMessage(
|
|
4563
|
+
function mapMemberMalformedMessage(id2, m) {
|
|
3428
4564
|
const keys = m.keys.map((k) => `\`${k}\``).join(", ");
|
|
3429
|
-
return `"${
|
|
4565
|
+
return `"${id2}".${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`;
|
|
3430
4566
|
}
|
|
3431
4567
|
function resolveDescriptor(key, m, ctx) {
|
|
3432
4568
|
if (!isMapDescriptor(m)) return {
|
|
@@ -3780,11 +4916,11 @@ function retryBackoffs() {
|
|
|
3780
4916
|
}
|
|
3781
4917
|
return WORKFLOW_RETRY_BACKOFFS;
|
|
3782
4918
|
}
|
|
3783
|
-
function sleepUntilUnsupportedMessage(
|
|
3784
|
-
return `the engine does not execute \`sleepUntil\` yet (node "${
|
|
4919
|
+
function sleepUntilUnsupportedMessage(id2) {
|
|
4920
|
+
return `the engine does not execute \`sleepUntil\` yet (node "${id2}") \u2014 replace it with a \`sleep\` node with a \`duration\` in ms, e.g. { type: 'sleep', id: '${id2}', duration: ${SLEEP_UNTIL_REPLACEMENT.duration} }`;
|
|
3785
4921
|
}
|
|
3786
|
-
function armSubrunUnsupportedMessage(
|
|
3787
|
-
return `the engine does not execute the implicit \`${workflowId}\` arm subrun (node "${
|
|
4922
|
+
function armSubrunUnsupportedMessage(id2, workflowId) {
|
|
4923
|
+
return `the engine does not execute the implicit \`${workflowId}\` arm subrun (node "${id2}") \u2014 a [map, step] container arm is the step itself with the map as its \`input\` since lua-cli 3.32.4; re-run \`lua compile\` with the current CLI (a hand-written artifact: put the map on the arm node's \`input\` and drop the \`workflow\` wrapper)`;
|
|
3788
4924
|
}
|
|
3789
4925
|
function fillPolicy(node, defaultTimeout) {
|
|
3790
4926
|
if (node.tier === void 0 && node.workspace !== void 0 && node.workspace !== "inherit") node.tier = "job";
|
|
@@ -4044,20 +5180,20 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4044
5180
|
const seen = /* @__PURE__ */ new Map();
|
|
4045
5181
|
let nodeCount = 0;
|
|
4046
5182
|
const upstream = /* @__PURE__ */ new Set();
|
|
4047
|
-
const checkId = /* @__PURE__ */ __name4((
|
|
5183
|
+
const checkId = /* @__PURE__ */ __name4((id2, path3) => {
|
|
4048
5184
|
nodeCount += 1;
|
|
4049
|
-
if (seen.has(
|
|
4050
|
-
err("duplicate-step-id", `step id "${
|
|
5185
|
+
if (seen.has(id2)) {
|
|
5186
|
+
err("duplicate-step-id", `step id "${id2}" is declared twice (first at ${seen.get(id2)})`, path3, id2);
|
|
4051
5187
|
} else {
|
|
4052
|
-
seen.set(
|
|
5188
|
+
seen.set(id2, path3);
|
|
4053
5189
|
}
|
|
4054
5190
|
}, "checkId");
|
|
4055
5191
|
const checkPolicyEnums = /* @__PURE__ */ __name4((node, path3) => {
|
|
4056
|
-
const
|
|
5192
|
+
const id2 = singleId(node);
|
|
4057
5193
|
const check = /* @__PURE__ */ __name4((member, allowed) => {
|
|
4058
5194
|
const value22 = node[member];
|
|
4059
5195
|
if (value22 === void 0 || typeof value22 === "string" && allowed.includes(value22)) return;
|
|
4060
|
-
err("invalid-envelope", `\`${member}\` must be ${allowed.map((a) => `'${a}'`).join(" | ")} (got ${JSON.stringify(value22)})`, `${path3}.${member}`,
|
|
5196
|
+
err("invalid-envelope", `\`${member}\` must be ${allowed.map((a) => `'${a}'`).join(" | ")} (got ${JSON.stringify(value22)})`, `${path3}.${member}`, id2);
|
|
4061
5197
|
}, "check");
|
|
4062
5198
|
check("sideEffects", WORKFLOW_SIDE_EFFECTS);
|
|
4063
5199
|
check("jobResources", WORKFLOW_JOB_RESOURCES);
|
|
@@ -4065,46 +5201,46 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4065
5201
|
const checkRetry = /* @__PURE__ */ __name4((node, path3) => {
|
|
4066
5202
|
const r = node.retry;
|
|
4067
5203
|
if (!r) return;
|
|
4068
|
-
const
|
|
5204
|
+
const id2 = singleId(node);
|
|
4069
5205
|
const unknown = unknownWorkflowRetryMembers(r);
|
|
4070
|
-
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path3}.retry`,
|
|
5206
|
+
if (unknown.length) err("invalid-envelope", workflowRetryUnknownMembersMessage(unknown), `${path3}.retry`, id2);
|
|
4071
5207
|
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
4072
5208
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
4073
|
-
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path3}.retry.maxAttempts`,
|
|
5209
|
+
err(over ? "cap-exceeded" : "invalid-envelope", workflowRetryMaxAttemptsMessage(r.maxAttempts), `${path3}.retry.maxAttempts`, id2);
|
|
4074
5210
|
}
|
|
4075
5211
|
const backoffs = retryBackoffs();
|
|
4076
5212
|
if (r.backoff !== void 0 && !backoffs.includes(r.backoff)) {
|
|
4077
5213
|
const list = backoffs.map((b) => `'${b}'`).join(" | ");
|
|
4078
|
-
err("backoff-invalid", `retry.backoff must be ${list}`, `${path3}.retry.backoff`,
|
|
5214
|
+
err("backoff-invalid", `retry.backoff must be ${list}`, `${path3}.retry.backoff`, id2);
|
|
4079
5215
|
}
|
|
4080
5216
|
if (r.backoffSeconds !== void 0 && r.backoffSeconds < 0) {
|
|
4081
|
-
err("backoff-invalid", "retry.backoffSeconds must be \u2265 0", `${path3}.retry.backoffSeconds`,
|
|
5217
|
+
err("backoff-invalid", "retry.backoffSeconds must be \u2265 0", `${path3}.retry.backoffSeconds`, id2);
|
|
4082
5218
|
}
|
|
4083
5219
|
if (r.maxBackoffSeconds !== void 0) {
|
|
4084
5220
|
if (r.backoff !== "exponential") {
|
|
4085
|
-
err("backoff-invalid", "retry.maxBackoffSeconds is only meaningful with backoff:'exponential'", `${path3}.retry`,
|
|
5221
|
+
err("backoff-invalid", "retry.maxBackoffSeconds is only meaningful with backoff:'exponential'", `${path3}.retry`, id2);
|
|
4086
5222
|
} else if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) {
|
|
4087
|
-
err("backoff-invalid", "retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds", `${path3}.retry.maxBackoffSeconds`,
|
|
5223
|
+
err("backoff-invalid", "retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds", `${path3}.retry.maxBackoffSeconds`, id2);
|
|
4088
5224
|
}
|
|
4089
5225
|
}
|
|
4090
5226
|
}, "checkRetry");
|
|
4091
5227
|
const checkTimeout = /* @__PURE__ */ __name4((node, path3) => {
|
|
4092
5228
|
const t = node.timeoutSeconds;
|
|
4093
5229
|
if (t === void 0) return;
|
|
4094
|
-
const
|
|
5230
|
+
const id2 = singleId(node);
|
|
4095
5231
|
if (!Number.isInteger(t) || t < 1) {
|
|
4096
|
-
err("timeout-out-of-range", `timeoutSeconds must be an integer \u2265 1 (got ${t})`, `${path3}.timeoutSeconds`,
|
|
5232
|
+
err("timeout-out-of-range", `timeoutSeconds must be an integer \u2265 1 (got ${t})`, `${path3}.timeoutSeconds`, id2);
|
|
4097
5233
|
return;
|
|
4098
5234
|
}
|
|
4099
5235
|
if (node.tier === "job") {
|
|
4100
5236
|
const cap = node.type === "agent" ? caps.maxJobTimeoutSeconds : caps.maxJobSegmentSeconds;
|
|
4101
5237
|
if (t > cap) {
|
|
4102
|
-
err("job-timeout-exceeds-cap", `timeoutSeconds ${t} exceeds the Job-tier cap of ${cap} s`, `${path3}.timeoutSeconds`,
|
|
5238
|
+
err("job-timeout-exceeds-cap", `timeoutSeconds ${t} exceeds the Job-tier cap of ${cap} s`, `${path3}.timeoutSeconds`, id2);
|
|
4103
5239
|
} else if (node.type === "agent" && t > caps.maxJobSegmentSeconds && !node.workspace) {
|
|
4104
|
-
err("long-job-requires-workspace", `steps longer than 4 h checkpoint to the run workspace \u2014 add workspace:{mount:'rw'} (and workspace on createWorkflow) or split the step`, `${path3}.timeoutSeconds`,
|
|
5240
|
+
err("long-job-requires-workspace", `steps longer than 4 h checkpoint to the run workspace \u2014 add workspace:{mount:'rw'} (and workspace on createWorkflow) or split the step`, `${path3}.timeoutSeconds`, id2);
|
|
4105
5241
|
}
|
|
4106
5242
|
} else if (t > caps.maxWorkerTimeoutSeconds) {
|
|
4107
|
-
err("timeout-exceeds-tier", `timeoutSeconds ${t} exceeds the worker tier's ${caps.maxWorkerTimeoutSeconds} s \u2014 steps longer than 10 min run on the Job tier: add tier:'job' (up to ${caps.maxJobSegmentSeconds} s)`, `${path3}.timeoutSeconds`,
|
|
5243
|
+
err("timeout-exceeds-tier", `timeoutSeconds ${t} exceeds the worker tier's ${caps.maxWorkerTimeoutSeconds} s \u2014 steps longer than 10 min run on the Job tier: add tier:'job' (up to ${caps.maxJobSegmentSeconds} s)`, `${path3}.timeoutSeconds`, id2);
|
|
4108
5244
|
}
|
|
4109
5245
|
}, "checkTimeout");
|
|
4110
5246
|
const checkSpecialistRole = /* @__PURE__ */ __name4((node, path3) => {
|
|
@@ -4168,32 +5304,32 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4168
5304
|
return void 0;
|
|
4169
5305
|
}, "jobClassifiablePin");
|
|
4170
5306
|
const checkTier = /* @__PURE__ */ __name4((node, path3) => {
|
|
4171
|
-
const
|
|
5307
|
+
const id2 = singleId(node);
|
|
4172
5308
|
if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
|
|
4173
|
-
err("workspace-requires-job-tier", "a step mounting a workspace must be tier:'job'", `${path3}.workspace`,
|
|
5309
|
+
err("workspace-requires-job-tier", "a step mounting a workspace must be tier:'job'", `${path3}.workspace`, id2);
|
|
4174
5310
|
}
|
|
4175
5311
|
if (node.harness !== void 0 && node.tier !== "job") {
|
|
4176
|
-
err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path3}.harness`,
|
|
5312
|
+
err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path3}.harness`, id2);
|
|
4177
5313
|
}
|
|
4178
5314
|
const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
|
|
4179
5315
|
if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
|
|
4180
|
-
err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path3}.harness`,
|
|
5316
|
+
err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path3}.harness`, id2);
|
|
4181
5317
|
}
|
|
4182
5318
|
if (isJobTier(node) && provider !== null && opts.policy?.jobProviders && !opts.policy.jobProviders.includes(provider)) {
|
|
4183
|
-
err("job-tier-provider-unsupported", `model provider '${provider}' is outside LUA_WF_JOB_PROVIDERS [${opts.policy.jobProviders.join(", ")}]`, `${path3}.model`,
|
|
5319
|
+
err("job-tier-provider-unsupported", `model provider '${provider}' is outside LUA_WF_JOB_PROVIDERS [${opts.policy.jobProviders.join(", ")}]`, `${path3}.model`, id2);
|
|
4184
5320
|
}
|
|
4185
5321
|
}, "checkTier");
|
|
4186
5322
|
const checkModel = /* @__PURE__ */ __name4((node, path3) => {
|
|
4187
5323
|
if (node.type !== "agent" || typeof node.model !== "string") return;
|
|
4188
|
-
const
|
|
5324
|
+
const id2 = singleId(node);
|
|
4189
5325
|
const parsed = parseModelTemplate(node.model);
|
|
4190
5326
|
if (parsed.kind === "invalid") {
|
|
4191
|
-
err("model-template-invalid", parsed.message, `${path3}.model`,
|
|
5327
|
+
err("model-template-invalid", parsed.message, `${path3}.model`, id2);
|
|
4192
5328
|
return;
|
|
4193
5329
|
}
|
|
4194
5330
|
if (parsed.kind === "template" && parsed.template.default === void 0) {
|
|
4195
5331
|
if (isJobTier(node)) {
|
|
4196
|
-
err("model-template-default-required", modelTemplateDefaultRequiredMessage(node.model), `${path3}.model`,
|
|
5332
|
+
err("model-template-default-required", modelTemplateDefaultRequiredMessage(node.model), `${path3}.model`, id2);
|
|
4197
5333
|
}
|
|
4198
5334
|
return;
|
|
4199
5335
|
}
|
|
@@ -4206,12 +5342,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4206
5342
|
if (registry === "unavailable") {
|
|
4207
5343
|
const trimmed = pin.trim();
|
|
4208
5344
|
if (trimmed && !normalizeModelId(trimmed, []).ok) {
|
|
4209
|
-
warn("model-unresolved", inContext(`model "${trimmed}" could not be checked against the approved-model registry (unavailable at push) \u2014 it dispatches only if it resolves there (a provider/model registry code, or a bare id exactly one approved model carries)`), `${path3}.model`,
|
|
5345
|
+
warn("model-unresolved", inContext(`model "${trimmed}" could not be checked against the approved-model registry (unavailable at push) \u2014 it dispatches only if it resolves there (a provider/model registry code, or a bare id exactly one approved model carries)`), `${path3}.model`, id2);
|
|
4210
5346
|
}
|
|
4211
5347
|
return;
|
|
4212
5348
|
}
|
|
4213
5349
|
const resolved = normalizeModelId(pin, registry);
|
|
4214
|
-
if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path3}.model`,
|
|
5350
|
+
if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path3}.model`, id2);
|
|
4215
5351
|
}, "checkModel");
|
|
4216
5352
|
const checkTaskClass = /* @__PURE__ */ __name4((node, path3) => {
|
|
4217
5353
|
if (node.type !== "agent" || node.taskClass === void 0) return;
|
|
@@ -4220,46 +5356,46 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4220
5356
|
err("task-class-without-model", `taskClass '${String(node.taskClass)}' needs a \`model\` on a pushed definition \u2014 write a class (model: 'class/fast' | 'class/balanced' | 'class/strong') or an approved provider/model code; nothing maps a task class to a model at dispatch, so a step with neither would run on the agent\u2019s own model`, `${path3}.taskClass`, singleId(node));
|
|
4221
5357
|
}, "checkTaskClass");
|
|
4222
5358
|
const checkWorkspace = /* @__PURE__ */ __name4((node, path3) => {
|
|
4223
|
-
const
|
|
5359
|
+
const id2 = singleId(node);
|
|
4224
5360
|
const ws = workspaceOf(node);
|
|
4225
5361
|
if (isJobTier(node) && opts.policy && opts.policy.jobTier !== true) {
|
|
4226
|
-
err("job-tier-disabled", `"${
|
|
5362
|
+
err("job-tier-disabled", `"${id2}" runs on the Job tier but the org's workflowPolicy.jobTier is off \u2014 an org admin enables it (lua features workflows.caps.jobTier true)`, `${path3}.tier`, id2);
|
|
4227
5363
|
}
|
|
4228
5364
|
const tools = jobToolsOf(node);
|
|
4229
5365
|
if (tools !== void 0) {
|
|
4230
5366
|
if (!isJobTier(node)) {
|
|
4231
|
-
err("job-tools-require-job-tier", "`jobTools` needs tier:'job'", `${path3}.jobTools`,
|
|
5367
|
+
err("job-tools-require-job-tier", "`jobTools` needs tier:'job'", `${path3}.jobTools`, id2);
|
|
4232
5368
|
}
|
|
4233
5369
|
const unknown = (Array.isArray(tools) ? tools : [
|
|
4234
5370
|
tools
|
|
4235
5371
|
]).filter((t) => !WORKFLOW_JOB_TOOLS.includes(t));
|
|
4236
5372
|
if (unknown.length > 0) {
|
|
4237
|
-
err("job-tools-unknown", `jobTools ${JSON.stringify(unknown)} outside WORKFLOW_JOB_TOOLS [${WORKFLOW_JOB_TOOLS.join(", ")}]`, `${path3}.jobTools`,
|
|
5373
|
+
err("job-tools-unknown", `jobTools ${JSON.stringify(unknown)} outside WORKFLOW_JOB_TOOLS [${WORKFLOW_JOB_TOOLS.join(", ")}]`, `${path3}.jobTools`, id2);
|
|
4238
5374
|
}
|
|
4239
5375
|
if (node.type === "agent" && (Array.isArray(tools) ? tools : [
|
|
4240
5376
|
tools
|
|
4241
5377
|
]).includes("gh")) {
|
|
4242
|
-
warn("gh-on-coding-turn", `"${
|
|
5378
|
+
warn("gh-on-coding-turn", `"${id2}" grants the gh tool on a coding turn \u2014 the pod can open/merge PRs on the workspace repo (purpose:'gh' token, pull_requests:write + contents:write)`, `${path3}.jobTools`, id2);
|
|
4243
5379
|
}
|
|
4244
5380
|
}
|
|
4245
5381
|
if (node.type === "agent" && ws && ws !== "inherit" && ws.mount === "ro" && Array.isArray(tools) && effectiveJobTools(tools, true).length === 0) {
|
|
4246
|
-
warn("ro-step-has-no-tools", `"${
|
|
5382
|
+
warn("ro-step-has-no-tools", `"${id2}" mounts the workspace read-only and every jobTool it declares (${JSON.stringify(tools)}) is one the ro mount drops [${WORKFLOW_JOB_READ_ONLY_DROPPED.join(", ")}] \u2014 the coding turn would run with no tools at all; keep a read-only tool (read/glob/grep, gh) or mount rw`, `${path3}.jobTools`, id2);
|
|
4247
5383
|
}
|
|
4248
5384
|
if (ws && ws !== "inherit") {
|
|
4249
5385
|
if (!envelopeWorkspace && !opts.mayInherit) {
|
|
4250
|
-
err("workspace-not-declared", `"${
|
|
5386
|
+
err("workspace-not-declared", `"${id2}" mounts a workspace but the workflow declares none \u2014 add workspace:{kind, \u2026} on createWorkflow`, `${path3}.workspace`, id2);
|
|
4251
5387
|
}
|
|
4252
5388
|
if (ws.isolation === "worktree" && envelopeWorkspace?.kind === "empty") {
|
|
4253
|
-
err("worktree-requires-git-workspace", `"${
|
|
5389
|
+
err("worktree-requires-git-workspace", `"${id2}": isolation:'worktree' needs a kind:'git' workspace (the envelope declares kind:'empty')`, `${path3}.workspace.isolation`, id2);
|
|
4254
5390
|
}
|
|
4255
5391
|
}
|
|
4256
5392
|
if (node.type === "workflow" && ws === "inherit") {
|
|
4257
5393
|
if (!envelopeWorkspace) {
|
|
4258
|
-
err("workspace-inherit-without-parent-workspace", `"${
|
|
5394
|
+
err("workspace-inherit-without-parent-workspace", `"${id2}": workspace:'inherit' but the parent workflow declares no workspace \u2014 there is nothing to inherit`, `${path3}.workspace`, id2);
|
|
4259
5395
|
}
|
|
4260
5396
|
const child = opts.resolveWorkflow?.(node.workflowId);
|
|
4261
5397
|
if (child?.workspace) {
|
|
4262
|
-
err("workspace-inherit-conflict", `"${
|
|
5398
|
+
err("workspace-inherit-conflict", `"${id2}": workspace:'inherit' on "${node.workflowId}", which declares its own workspace`, `${path3}.workspace`, id2);
|
|
4263
5399
|
}
|
|
4264
5400
|
}
|
|
4265
5401
|
}, "checkWorkspace");
|
|
@@ -4268,20 +5404,20 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4268
5404
|
const schema = node.type === "step" ? node.step.outputSchema : node.type === "agent" ? node.outputSchema : void 0;
|
|
4269
5405
|
if (schema !== void 0) outputSchemas.set(singleId(node), schema);
|
|
4270
5406
|
}, "recordOutputSchema");
|
|
4271
|
-
const checkMapMembers = /* @__PURE__ */ __name4((cfg, basePath,
|
|
5407
|
+
const checkMapMembers = /* @__PURE__ */ __name4((cfg, basePath, id2) => {
|
|
4272
5408
|
for (const m of malformedMapMembers(cfg)) {
|
|
4273
|
-
warn(MAP_MEMBER_MALFORMED_CODE, mapMemberMalformedMessage(
|
|
5409
|
+
warn(MAP_MEMBER_MALFORMED_CODE, mapMemberMalformedMessage(id2, m), `${basePath}.${m.member}`, id2);
|
|
4274
5410
|
}
|
|
4275
5411
|
}, "checkMapMembers");
|
|
4276
5412
|
const checkInputShape = /* @__PURE__ */ __name4((node, path3) => {
|
|
4277
5413
|
const input = node.input;
|
|
4278
5414
|
if (input === void 0) return;
|
|
4279
|
-
const
|
|
5415
|
+
const id2 = singleId(node);
|
|
4280
5416
|
if (input !== null && typeof input === "object" && !Array.isArray(input)) {
|
|
4281
|
-
checkMapMembers(input, `${path3}.input`,
|
|
5417
|
+
checkMapMembers(input, `${path3}.input`, id2);
|
|
4282
5418
|
return;
|
|
4283
5419
|
}
|
|
4284
|
-
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)})`, `${path3}.input`,
|
|
5420
|
+
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)})`, `${path3}.input`, id2);
|
|
4285
5421
|
}, "checkInputShape");
|
|
4286
5422
|
const checkBodyInput = /* @__PURE__ */ __name4((body, path3, container) => {
|
|
4287
5423
|
if (body.type === "workflow" || body.input === void 0) return;
|
|
@@ -4572,7 +5708,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
4572
5708
|
default:
|
|
4573
5709
|
err("invalid-envelope", `unknown entry type "${entry.type}"`, path3);
|
|
4574
5710
|
}
|
|
4575
|
-
for (const
|
|
5711
|
+
for (const id2 of declared) upstream.add(id2);
|
|
4576
5712
|
});
|
|
4577
5713
|
if (nodeCount > caps.maxNodes) {
|
|
4578
5714
|
err("cap-exceeded", `${nodeCount} nodes exceeds the static cap of ${caps.maxNodes}`, "definition.graph");
|
|
@@ -4647,19 +5783,19 @@ function hashGraph(g) {
|
|
|
4647
5783
|
function compilePlan(g) {
|
|
4648
5784
|
const steps = {};
|
|
4649
5785
|
const order = [];
|
|
4650
|
-
const addNode = /* @__PURE__ */ __name4((
|
|
4651
|
-
if (
|
|
4652
|
-
throw new WorkflowPlanError("duplicate-step-id", `Duplicate step id "${
|
|
5786
|
+
const addNode = /* @__PURE__ */ __name4((id2, node) => {
|
|
5787
|
+
if (id2 in steps) {
|
|
5788
|
+
throw new WorkflowPlanError("duplicate-step-id", `Duplicate step id "${id2}" in definition.graph`);
|
|
4653
5789
|
}
|
|
4654
|
-
steps[
|
|
4655
|
-
order.push(
|
|
5790
|
+
steps[id2] = node;
|
|
5791
|
+
order.push(id2);
|
|
4656
5792
|
}, "addNode");
|
|
4657
5793
|
let prevTails = [];
|
|
4658
5794
|
const foreachJoinToEntry = /* @__PURE__ */ new Map();
|
|
4659
5795
|
g.definition.graph.forEach((entry, entryIndex) => {
|
|
4660
5796
|
if (isArmStep(entry)) {
|
|
4661
|
-
const
|
|
4662
|
-
addNode(
|
|
5797
|
+
const id2 = armStepId(entry);
|
|
5798
|
+
addNode(id2, {
|
|
4663
5799
|
kind: armStepKind(entry),
|
|
4664
5800
|
dependsOn: prevTails,
|
|
4665
5801
|
downstream: [],
|
|
@@ -4667,7 +5803,7 @@ function compilePlan(g) {
|
|
|
4667
5803
|
entry
|
|
4668
5804
|
});
|
|
4669
5805
|
prevTails = [
|
|
4670
|
-
|
|
5806
|
+
id2
|
|
4671
5807
|
];
|
|
4672
5808
|
return;
|
|
4673
5809
|
}
|
|
@@ -4806,10 +5942,10 @@ function compilePlan(g) {
|
|
|
4806
5942
|
throw new WorkflowPlanError("unknown-entry-type", `Unknown graph entry type "${entry.type}" at definition.graph[${entryIndex}]`);
|
|
4807
5943
|
}
|
|
4808
5944
|
});
|
|
4809
|
-
for (const
|
|
4810
|
-
for (const dep of steps[
|
|
5945
|
+
for (const id2 of order) {
|
|
5946
|
+
for (const dep of steps[id2].dependsOn) {
|
|
4811
5947
|
const target = steps[dep] ?? (foreachJoinToEntry.has(dep) ? steps[foreachJoinToEntry.get(dep)] : void 0);
|
|
4812
|
-
target?.downstream.push(
|
|
5948
|
+
target?.downstream.push(id2);
|
|
4813
5949
|
}
|
|
4814
5950
|
}
|
|
4815
5951
|
return {
|
|
@@ -4975,15 +6111,15 @@ function renderRef(ref) {
|
|
|
4975
6111
|
return ref.path;
|
|
4976
6112
|
}
|
|
4977
6113
|
function step(s) {
|
|
4978
|
-
const
|
|
6114
|
+
const id2 = stepIdOf(s);
|
|
4979
6115
|
return {
|
|
4980
6116
|
path: /* @__PURE__ */ __name4((p) => ({
|
|
4981
|
-
path: p === "" ? `stepResults.${
|
|
6117
|
+
path: p === "" ? `stepResults.${id2}` : `stepResults.${id2}.${p}`
|
|
4982
6118
|
}), "path")
|
|
4983
6119
|
};
|
|
4984
6120
|
}
|
|
4985
|
-
function stepOf(
|
|
4986
|
-
return step(
|
|
6121
|
+
function stepOf(id2) {
|
|
6122
|
+
return step(id2);
|
|
4987
6123
|
}
|
|
4988
6124
|
function init(path3) {
|
|
4989
6125
|
return {
|
|
@@ -5065,18 +6201,18 @@ function resolvePlacements(calls) {
|
|
|
5065
6201
|
const declared = /* @__PURE__ */ new Map();
|
|
5066
6202
|
const placedBy = /* @__PURE__ */ new Map();
|
|
5067
6203
|
const allIds = /* @__PURE__ */ new Map();
|
|
5068
|
-
const claimId = /* @__PURE__ */ __name4((
|
|
5069
|
-
const first = allIds.get(
|
|
6204
|
+
const claimId = /* @__PURE__ */ __name4((id2, callIndex) => {
|
|
6205
|
+
const first = allIds.get(id2);
|
|
5070
6206
|
if (first !== void 0 && first !== callIndex) {
|
|
5071
6207
|
issues.push({
|
|
5072
6208
|
code: "duplicate-step-id",
|
|
5073
|
-
message: `step id "${
|
|
6209
|
+
message: `step id "${id2}" is declared more than once (calls #${first} and #${callIndex})`,
|
|
5074
6210
|
callIndex,
|
|
5075
|
-
stepId:
|
|
6211
|
+
stepId: id2
|
|
5076
6212
|
});
|
|
5077
6213
|
return;
|
|
5078
6214
|
}
|
|
5079
|
-
allIds.set(
|
|
6215
|
+
allIds.set(id2, callIndex);
|
|
5080
6216
|
}, "claimId");
|
|
5081
6217
|
calls.forEach((call, i) => {
|
|
5082
6218
|
switch (call.kind) {
|
|
@@ -5088,7 +6224,7 @@ function resolvePlacements(calls) {
|
|
|
5088
6224
|
});
|
|
5089
6225
|
break;
|
|
5090
6226
|
case "entry":
|
|
5091
|
-
for (const
|
|
6227
|
+
for (const id2 of entryIds(call.entry)) claimId(id2, i);
|
|
5092
6228
|
break;
|
|
5093
6229
|
case "parallel":
|
|
5094
6230
|
for (const arm of call.arms) if ("node" in arm) claimId(nodeIdOf(arm.node), i);
|
|
@@ -5107,42 +6243,42 @@ function resolvePlacements(calls) {
|
|
|
5107
6243
|
});
|
|
5108
6244
|
const armMapPlacementIssue = /* @__PURE__ */ __name4((node, ref, i, container) => {
|
|
5109
6245
|
if (!ref.armMap || node.type === "mapping" || isHitlNode2(node)) return void 0;
|
|
5110
|
-
const
|
|
6246
|
+
const id2 = nodeIdOf(node);
|
|
5111
6247
|
if ((container === "foreach" || container === "loop") && node.type !== "workflow") {
|
|
5112
6248
|
return {
|
|
5113
6249
|
code: "mapping-placement",
|
|
5114
|
-
message: container === "foreach" ? `foreach body "${
|
|
6250
|
+
message: container === "foreach" ? `foreach body "${id2}": a [map, step] body is not supported \u2014 the body receives each item as its input; map the items before the foreach instead (foreach(step, { items: \u2026 }) or a .map() before it)` : `loop body "${id2}": a [map, step] body is not supported \u2014 the body receives the previous output as its input; put the .map() before the loop instead`,
|
|
5115
6251
|
callIndex: i,
|
|
5116
|
-
stepId:
|
|
6252
|
+
stepId: id2
|
|
5117
6253
|
};
|
|
5118
6254
|
}
|
|
5119
6255
|
if (node.input !== void 0) {
|
|
5120
6256
|
return {
|
|
5121
6257
|
code: "mapping-placement",
|
|
5122
|
-
message: `"${
|
|
6258
|
+
message: `"${id2}": the [map, step] arm mapping and the node's own input map would both bind its input \u2014 keep one (drop the arm map, or the \`input\` on the declaration)`,
|
|
5123
6259
|
callIndex: i,
|
|
5124
|
-
stepId:
|
|
6260
|
+
stepId: id2
|
|
5125
6261
|
};
|
|
5126
6262
|
}
|
|
5127
6263
|
return void 0;
|
|
5128
6264
|
}, "armMapPlacementIssue");
|
|
5129
6265
|
const hitlPlacementIssue = /* @__PURE__ */ __name4((node, ref, i, container) => {
|
|
5130
6266
|
if (!isHitlNode2(node)) return void 0;
|
|
5131
|
-
const
|
|
6267
|
+
const id2 = node.id;
|
|
5132
6268
|
if (ref.armMap) {
|
|
5133
6269
|
return {
|
|
5134
6270
|
code: "node-type-unsupported-in-container",
|
|
5135
|
-
message: workflowHitlArmShapeMessage(node.type,
|
|
6271
|
+
message: workflowHitlArmShapeMessage(node.type, id2, "mapped-arm"),
|
|
5136
6272
|
callIndex: i,
|
|
5137
|
-
stepId:
|
|
6273
|
+
stepId: id2
|
|
5138
6274
|
};
|
|
5139
6275
|
}
|
|
5140
6276
|
if (container !== "place" && !workflowContainerRunsHitlArm(container)) {
|
|
5141
6277
|
return {
|
|
5142
6278
|
code: "node-type-unsupported-in-container",
|
|
5143
|
-
message: workflowHitlArmUnsupportedMessage(node.type,
|
|
6279
|
+
message: workflowHitlArmUnsupportedMessage(node.type, id2, container),
|
|
5144
6280
|
callIndex: i,
|
|
5145
|
-
stepId:
|
|
6281
|
+
stepId: id2
|
|
5146
6282
|
};
|
|
5147
6283
|
}
|
|
5148
6284
|
return void 0;
|
|
@@ -5248,8 +6384,8 @@ function resolvePlacements(calls) {
|
|
|
5248
6384
|
graph.push(call.entry);
|
|
5249
6385
|
return;
|
|
5250
6386
|
case "declare": {
|
|
5251
|
-
const
|
|
5252
|
-
if (placedBy.has(
|
|
6387
|
+
const id2 = nodeIdOf(call.node);
|
|
6388
|
+
if (placedBy.has(id2)) return;
|
|
5253
6389
|
graph.push(call.node);
|
|
5254
6390
|
return;
|
|
5255
6391
|
}
|
|
@@ -5380,14 +6516,14 @@ function seedLedgerFromRun(run, steps, targetPlan, opts = {}) {
|
|
|
5380
6516
|
const seeded = [];
|
|
5381
6517
|
const unseeded = [];
|
|
5382
6518
|
const known = new Set(Object.keys(targetPlan.steps));
|
|
5383
|
-
const parentOf = /* @__PURE__ */ __name4((
|
|
5384
|
-
const m = /^(.*)(\[\d+\]|#\d+)$/.exec(
|
|
6519
|
+
const parentOf = /* @__PURE__ */ __name4((id2) => {
|
|
6520
|
+
const m = /^(.*)(\[\d+\]|#\d+)$/.exec(id2);
|
|
5385
6521
|
return m ? m[1] : void 0;
|
|
5386
6522
|
}, "parentOf");
|
|
5387
|
-
const dependsOf = /* @__PURE__ */ __name4((
|
|
5388
|
-
const node = targetPlan.steps[
|
|
6523
|
+
const dependsOf = /* @__PURE__ */ __name4((id2) => {
|
|
6524
|
+
const node = targetPlan.steps[id2];
|
|
5389
6525
|
if (node) return node.dependsOn;
|
|
5390
|
-
const parent = parentOf(
|
|
6526
|
+
const parent = parentOf(id2);
|
|
5391
6527
|
return parent && targetPlan.steps[parent] ? [
|
|
5392
6528
|
parent
|
|
5393
6529
|
] : [];
|
|
@@ -5400,23 +6536,23 @@ function seedLedgerFromRun(run, steps, targetPlan, opts = {}) {
|
|
|
5400
6536
|
walk22.push(s.stepId);
|
|
5401
6537
|
}
|
|
5402
6538
|
}
|
|
5403
|
-
for (const
|
|
5404
|
-
const row = byId.get(
|
|
6539
|
+
for (const id2 of walk22) {
|
|
6540
|
+
const row = byId.get(id2);
|
|
5405
6541
|
if (!row || row.status !== "completed") continue;
|
|
5406
|
-
if (!dependsOf(
|
|
5407
|
-
unseeded.push(
|
|
6542
|
+
if (!dependsOf(id2).every((d) => seededIds.has(d))) {
|
|
6543
|
+
unseeded.push(id2);
|
|
5408
6544
|
continue;
|
|
5409
6545
|
}
|
|
5410
|
-
seededIds.add(
|
|
6546
|
+
seededIds.add(id2);
|
|
5411
6547
|
seeded.push({
|
|
5412
|
-
stepId:
|
|
6548
|
+
stepId: id2,
|
|
5413
6549
|
output: row.output,
|
|
5414
6550
|
attempt: row.attempt ?? 1,
|
|
5415
6551
|
effects: row.effects ?? {}
|
|
5416
6552
|
});
|
|
5417
6553
|
}
|
|
5418
6554
|
const dropped = steps.filter((s) => s.status === "completed" && !known.has(s.stepId) && !(parentOf(s.stepId) && known.has(parentOf(s.stepId)))).map((s) => s.stepId);
|
|
5419
|
-
const firstPending = targetPlan.order.find((
|
|
6555
|
+
const firstPending = targetPlan.order.find((id2) => !seededIds.has(id2));
|
|
5420
6556
|
const graphChanged = !!(opts.targetGraphHash && run.graphHash && opts.targetGraphHash !== run.graphHash);
|
|
5421
6557
|
return {
|
|
5422
6558
|
sourceRunId: run.id,
|
|
@@ -5471,37 +6607,37 @@ function replayLedger(g, ledger) {
|
|
|
5471
6607
|
startedAt: 0,
|
|
5472
6608
|
...ledger.requestContext
|
|
5473
6609
|
};
|
|
5474
|
-
const ctxFor = /* @__PURE__ */ __name4((
|
|
6610
|
+
const ctxFor = /* @__PURE__ */ __name4((id2) => ({
|
|
5475
6611
|
initData: ledger.initData,
|
|
5476
|
-
stepResults: ancestorResults(plan,
|
|
6612
|
+
stepResults: ancestorResults(plan, id2, rows22),
|
|
5477
6613
|
state: ledger.state ?? {},
|
|
5478
6614
|
requestContext
|
|
5479
6615
|
}), "ctxFor");
|
|
5480
6616
|
const verdicts = [];
|
|
5481
|
-
for (const
|
|
5482
|
-
const node = plan.steps[
|
|
5483
|
-
const recorded = rows22.get(
|
|
6617
|
+
for (const id2 of plan.order) {
|
|
6618
|
+
const node = plan.steps[id2];
|
|
6619
|
+
const recorded = rows22.get(id2);
|
|
5484
6620
|
if (!recorded || recorded.status === "pending" || recorded.status === "skipped") continue;
|
|
5485
6621
|
if (node.kind === "branch") {
|
|
5486
6622
|
const entry = node.entry;
|
|
5487
|
-
const taken = selectBranchArms(branchSpecFromConditional(entry), ctxFor(
|
|
6623
|
+
const taken = selectBranchArms(branchSpecFromConditional(entry), ctxFor(id2));
|
|
5488
6624
|
const recordedTaken = recorded.taken ?? inferTaken(entry, rows22);
|
|
5489
6625
|
verdicts.push({
|
|
5490
|
-
stepId:
|
|
6626
|
+
stepId: id2,
|
|
5491
6627
|
kind: "branch",
|
|
5492
6628
|
recorded: recordedTaken,
|
|
5493
6629
|
local: taken,
|
|
5494
6630
|
diverged: canonical(recordedTaken) !== canonical(taken)
|
|
5495
6631
|
});
|
|
5496
|
-
} else if (node.kind === "map" && !
|
|
6632
|
+
} else if (node.kind === "map" && !id2.endsWith(".join") && recorded.status === "completed") {
|
|
5497
6633
|
const entry = node.entry;
|
|
5498
|
-
const resolved = resolveMapping(parseMapConfig(entry.mapConfig,
|
|
6634
|
+
const resolved = resolveMapping(parseMapConfig(entry.mapConfig, id2), ctxFor(id2));
|
|
5499
6635
|
const local = "error" in resolved ? {
|
|
5500
6636
|
error: resolved.error,
|
|
5501
6637
|
key: resolved.key
|
|
5502
6638
|
} : resolved.value;
|
|
5503
6639
|
verdicts.push({
|
|
5504
|
-
stepId:
|
|
6640
|
+
stepId: id2,
|
|
5505
6641
|
kind: "map",
|
|
5506
6642
|
recorded: recorded.output,
|
|
5507
6643
|
local,
|
|
@@ -5510,11 +6646,11 @@ function replayLedger(g, ledger) {
|
|
|
5510
6646
|
} else if (node.kind === "foreach") {
|
|
5511
6647
|
const entry = node.entry;
|
|
5512
6648
|
const source = node.dependsOn[0];
|
|
5513
|
-
const items = source ? ctxFor(
|
|
6649
|
+
const items = source ? ctxFor(id2).stepResults[source] : void 0;
|
|
5514
6650
|
const local = Array.isArray(items) ? items.length : void 0;
|
|
5515
6651
|
const recordedCount = recorded.itemCount ?? countChildren(entry, rows22);
|
|
5516
6652
|
verdicts.push({
|
|
5517
|
-
stepId:
|
|
6653
|
+
stepId: id2,
|
|
5518
6654
|
kind: "foreach",
|
|
5519
6655
|
recorded: recordedCount,
|
|
5520
6656
|
local,
|
|
@@ -5523,7 +6659,7 @@ function replayLedger(g, ledger) {
|
|
|
5523
6659
|
} else if (node.kind === "subrun" && recorded.status === "completed" && recorded.child) {
|
|
5524
6660
|
const local = subrunSettledOutput(recorded.child);
|
|
5525
6661
|
verdicts.push({
|
|
5526
|
-
stepId:
|
|
6662
|
+
stepId: id2,
|
|
5527
6663
|
kind: "subrun",
|
|
5528
6664
|
recorded: recorded.output,
|
|
5529
6665
|
local,
|
|
@@ -5549,7 +6685,7 @@ function replayResultOf(row, node) {
|
|
|
5549
6685
|
}
|
|
5550
6686
|
return void 0;
|
|
5551
6687
|
}
|
|
5552
|
-
function ancestorResults(plan,
|
|
6688
|
+
function ancestorResults(plan, id2, rows22) {
|
|
5553
6689
|
const out = {};
|
|
5554
6690
|
const joinAliased = /* @__PURE__ */ new Set();
|
|
5555
6691
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -5598,7 +6734,7 @@ function ancestorResults(plan, id, rows22) {
|
|
|
5598
6734
|
walk22(node.dependsOn);
|
|
5599
6735
|
}
|
|
5600
6736
|
}, "walk");
|
|
5601
|
-
walk22(plan.steps[
|
|
6737
|
+
walk22(plan.steps[id2]?.dependsOn ?? []);
|
|
5602
6738
|
return out;
|
|
5603
6739
|
}
|
|
5604
6740
|
function inferTaken(entry, rows22) {
|
|
@@ -5608,15 +6744,15 @@ function inferTaken(entry, rows22) {
|
|
|
5608
6744
|
entry.otherwise
|
|
5609
6745
|
] : []
|
|
5610
6746
|
];
|
|
5611
|
-
return arms.map(branchArmId).filter((
|
|
5612
|
-
const r = rows22.get(
|
|
6747
|
+
return arms.map(branchArmId).filter((id2) => {
|
|
6748
|
+
const r = rows22.get(id2);
|
|
5613
6749
|
return r !== void 0 && r.status !== "skipped" && r.status !== "pending";
|
|
5614
6750
|
});
|
|
5615
6751
|
}
|
|
5616
6752
|
function countChildren(entry, rows22) {
|
|
5617
6753
|
const body = branchArmId(entry.step);
|
|
5618
6754
|
let n2 = 0;
|
|
5619
|
-
for (const
|
|
6755
|
+
for (const id2 of rows22.keys()) if (id2.startsWith(`${body}[`)) n2 += 1;
|
|
5620
6756
|
return n2;
|
|
5621
6757
|
}
|
|
5622
6758
|
function isTerminalRunStatus(status) {
|
|
@@ -6884,8 +8020,8 @@ var init_dist2 = __esm({
|
|
|
6884
8020
|
fromKnowledge = /* @__PURE__ */ __name4((k) => ({
|
|
6885
8021
|
knowledge: k
|
|
6886
8022
|
}), "fromKnowledge");
|
|
6887
|
-
SideEffectsSchema =
|
|
6888
|
-
JobResourcesSchema =
|
|
8023
|
+
SideEffectsSchema = z5.enum(WORKFLOW_SIDE_EFFECTS);
|
|
8024
|
+
JobResourcesSchema = z5.enum(WORKFLOW_JOB_RESOURCES);
|
|
6889
8025
|
WORKFLOW_MODEL_TEMPLATE_ROOT = "initData";
|
|
6890
8026
|
WORKFLOW_MODEL_TEMPLATE_RE = /^\$\{\s*initData\.([A-Za-z0-9_.\-[\]]+)\s*(?:\|([^}]*))?\}$/;
|
|
6891
8027
|
PATH_SEGMENT_RE = /^[A-Za-z0-9_-]+(?:\[(?:0|[1-9]\d*)\])*$/;
|
|
@@ -7318,7 +8454,7 @@ var init_dist2 = __esm({
|
|
|
7318
8454
|
__name(replayLedger, "replayLedger");
|
|
7319
8455
|
__name4(replayLedger, "replayLedger");
|
|
7320
8456
|
JOIN = ".join";
|
|
7321
|
-
entryOfJoin = /* @__PURE__ */ __name4((
|
|
8457
|
+
entryOfJoin = /* @__PURE__ */ __name4((id2) => id2.endsWith(JOIN) ? id2.slice(0, -JOIN.length) : void 0, "entryOfJoin");
|
|
7322
8458
|
__name(replayResultOf, "replayResultOf");
|
|
7323
8459
|
__name4(replayResultOf, "replayResultOf");
|
|
7324
8460
|
__name(ancestorResults, "ancestorResults");
|
|
@@ -7607,8 +8743,8 @@ function createStep(s) {
|
|
|
7607
8743
|
function step2(s) {
|
|
7608
8744
|
return step(typeof s === "string" ? s : s.id);
|
|
7609
8745
|
}
|
|
7610
|
-
function stepOf2(
|
|
7611
|
-
return stepOf(
|
|
8746
|
+
function stepOf2(id2) {
|
|
8747
|
+
return stepOf(id2);
|
|
7612
8748
|
}
|
|
7613
8749
|
function schemaToJson(schema) {
|
|
7614
8750
|
if (schema === void 0 || schema === null) return void 0;
|
|
@@ -7812,16 +8948,16 @@ var init_workflow = __esm({
|
|
|
7812
8948
|
if (!isPredicate(p)) throw new LuaWorkflowBuildError("closure-predicate", `${where}: not a LuaPredicate`, "build predicates with eq/gt/inSet/exists/and/or/not");
|
|
7813
8949
|
return p;
|
|
7814
8950
|
}, "assertPredicate");
|
|
7815
|
-
assertRetry = /* @__PURE__ */ __name((r,
|
|
8951
|
+
assertRetry = /* @__PURE__ */ __name((r, id2) => {
|
|
7816
8952
|
if (!r) return;
|
|
7817
8953
|
if (!isWithinWorkflowRetryAttempts(r.maxAttempts)) {
|
|
7818
8954
|
const over = typeof r.maxAttempts === "number" && r.maxAttempts > WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
7819
|
-
throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${
|
|
8955
|
+
throw new LuaWorkflowBuildError(over ? "cap-exceeded" : "invalid-envelope", `"${id2}": ${workflowRetryMaxAttemptsMessage(r.maxAttempts)}`);
|
|
7820
8956
|
}
|
|
7821
|
-
if (r.backoff !== void 0 && !WORKFLOW_RETRY_BACKOFFS.includes(r.backoff)) throw new LuaWorkflowBuildError("backoff-invalid", `"${
|
|
8957
|
+
if (r.backoff !== void 0 && !WORKFLOW_RETRY_BACKOFFS.includes(r.backoff)) throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.backoff must be ${WORKFLOW_RETRY_BACKOFFS.map((b) => `'${b}'`).join(" | ")}`);
|
|
7822
8958
|
if (r.maxBackoffSeconds !== void 0) {
|
|
7823
|
-
if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${
|
|
7824
|
-
if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) throw new LuaWorkflowBuildError("backoff-invalid", `"${
|
|
8959
|
+
if (r.backoff !== "exponential") throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.maxBackoffSeconds is only meaningful with backoff:'exponential'`);
|
|
8960
|
+
if (r.maxBackoffSeconds <= 0 || r.backoffSeconds !== void 0 && r.maxBackoffSeconds < r.backoffSeconds) throw new LuaWorkflowBuildError("backoff-invalid", `"${id2}": retry.maxBackoffSeconds must be > 0 and \u2265 backoffSeconds`);
|
|
7825
8961
|
}
|
|
7826
8962
|
}, "assertRetry");
|
|
7827
8963
|
assertTimeout = /* @__PURE__ */ __name((node) => {
|
|
@@ -8019,8 +9155,8 @@ var init_workflow = __esm({
|
|
|
8019
9155
|
ref: arm
|
|
8020
9156
|
};
|
|
8021
9157
|
if (arm && typeof arm === "object" && isHitlEntry(arm)) {
|
|
8022
|
-
const
|
|
8023
|
-
throw new LuaWorkflowBuildError("invalid-step", `${where}: an approval / waitForSignal arm is placed by id \u2014 declare it with .approval(${JSON.stringify(
|
|
9158
|
+
const id2 = arm.id;
|
|
9159
|
+
throw new LuaWorkflowBuildError("invalid-step", `${where}: an approval / waitForSignal arm is placed by id \u2014 declare it with .approval(${JSON.stringify(id2 ?? "id")}, \u2026) / .waitForSignal(\u2026) and pass the id string`);
|
|
8024
9160
|
}
|
|
8025
9161
|
return {
|
|
8026
9162
|
node: this.registerStep(arm, where)
|
|
@@ -8140,14 +9276,14 @@ var init_workflow = __esm({
|
|
|
8140
9276
|
assertNoClosure(mapping, "map()");
|
|
8141
9277
|
this.recordEnvRefs(mapping);
|
|
8142
9278
|
this.mapCount += 1;
|
|
8143
|
-
let
|
|
8144
|
-
if (
|
|
9279
|
+
let id2 = opts?.id;
|
|
9280
|
+
if (id2 === void 0) {
|
|
8145
9281
|
this.unnamedMaps += 1;
|
|
8146
|
-
|
|
9282
|
+
id2 = `map_${this.mapCount}`;
|
|
8147
9283
|
}
|
|
8148
9284
|
const node = {
|
|
8149
9285
|
type: "mapping",
|
|
8150
|
-
id,
|
|
9286
|
+
id: id2,
|
|
8151
9287
|
mapConfig: canonicalJson(mapping)
|
|
8152
9288
|
};
|
|
8153
9289
|
return this.push({
|
|
@@ -8158,12 +9294,12 @@ var init_workflow = __esm({
|
|
|
8158
9294
|
sleep(ms, opts) {
|
|
8159
9295
|
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) throw new LuaWorkflowBuildError("invalid-envelope", "sleep(ms) takes a literal non-negative number");
|
|
8160
9296
|
this.sleepCount += 1;
|
|
8161
|
-
const
|
|
9297
|
+
const id2 = opts?.id ?? `sleep_${this.sleepCount}`;
|
|
8162
9298
|
return this.push({
|
|
8163
9299
|
kind: "entry",
|
|
8164
9300
|
entry: defined({
|
|
8165
9301
|
type: "sleep",
|
|
8166
|
-
id,
|
|
9302
|
+
id: id2,
|
|
8167
9303
|
duration: ms,
|
|
8168
9304
|
businessHours: opts?.businessHours
|
|
8169
9305
|
})
|
|
@@ -8171,13 +9307,13 @@ var init_workflow = __esm({
|
|
|
8171
9307
|
}
|
|
8172
9308
|
sleepUntil(iso, opts) {
|
|
8173
9309
|
this.sleepCount += 1;
|
|
8174
|
-
const
|
|
9310
|
+
const id2 = opts?.id ?? `sleep_${this.sleepCount}`;
|
|
8175
9311
|
if (typeof iso === "string") {
|
|
8176
9312
|
return this.push({
|
|
8177
9313
|
kind: "entry",
|
|
8178
9314
|
entry: defined({
|
|
8179
9315
|
type: "sleepUntil",
|
|
8180
|
-
id,
|
|
9316
|
+
id: id2,
|
|
8181
9317
|
date: iso,
|
|
8182
9318
|
businessHours: opts?.businessHours,
|
|
8183
9319
|
round: opts?.round
|
|
@@ -8190,7 +9326,7 @@ var init_workflow = __esm({
|
|
|
8190
9326
|
kind: "entry",
|
|
8191
9327
|
entry: {
|
|
8192
9328
|
type: "mapping",
|
|
8193
|
-
id: `${
|
|
9329
|
+
id: `${id2}_at`,
|
|
8194
9330
|
mapConfig: canonicalJson({
|
|
8195
9331
|
date: {
|
|
8196
9332
|
template: iso.template
|
|
@@ -8202,9 +9338,9 @@ var init_workflow = __esm({
|
|
|
8202
9338
|
kind: "entry",
|
|
8203
9339
|
entry: defined({
|
|
8204
9340
|
type: "sleepUntil",
|
|
8205
|
-
id,
|
|
9341
|
+
id: id2,
|
|
8206
9342
|
dateFrom: {
|
|
8207
|
-
step: `${
|
|
9343
|
+
step: `${id2}_at`,
|
|
8208
9344
|
path: "date"
|
|
8209
9345
|
},
|
|
8210
9346
|
businessHours: opts?.businessHours,
|
|
@@ -8212,35 +9348,35 @@ var init_workflow = __esm({
|
|
|
8212
9348
|
})
|
|
8213
9349
|
});
|
|
8214
9350
|
}
|
|
8215
|
-
agentStep(
|
|
8216
|
-
this.assertId(
|
|
9351
|
+
agentStep(id2, opts) {
|
|
9352
|
+
this.assertId(id2, "agentStep()");
|
|
8217
9353
|
if (!opts || typeof opts.agentId !== "string" && !(opts.agentId && typeof opts.agentId === "object" && "__envRef" in opts.agentId)) {
|
|
8218
|
-
throw new LuaWorkflowBuildError("invalid-envelope", `agentStep("${
|
|
9354
|
+
throw new LuaWorkflowBuildError("invalid-envelope", `agentStep("${id2}") needs an agentId`);
|
|
8219
9355
|
}
|
|
8220
9356
|
const tier = opts.tier ?? (opts.workspace ? "job" : void 0);
|
|
8221
|
-
if (opts.workspace && opts.tier !== void 0 && opts.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${
|
|
8222
|
-
if (opts.harness !== void 0 && tier !== "job") throw new LuaWorkflowBuildError("harness-requires-job-tier", `"${
|
|
8223
|
-
if (opts.toolScope?.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${
|
|
9357
|
+
if (opts.workspace && opts.tier !== void 0 && opts.tier !== "job") throw new LuaWorkflowBuildError("workspace-requires-job-tier", `"${id2}": a step mounting a workspace must be tier:'job'`);
|
|
9358
|
+
if (opts.harness !== void 0 && tier !== "job") throw new LuaWorkflowBuildError("harness-requires-job-tier", `"${id2}": harness is only legal on a tier:'job' agent step`);
|
|
9359
|
+
if (opts.toolScope?.jobTools && tier !== "job") throw new LuaWorkflowBuildError("cap-exceeded", `"${id2}": toolScope.jobTools require tier:'job' (job-tools-require-job-tier)`);
|
|
8224
9360
|
for (const m of WORKFLOW_JOB_RANGE_MEMBERS) {
|
|
8225
9361
|
if (opts[m] === void 0) continue;
|
|
8226
|
-
if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${
|
|
9362
|
+
if (tier !== "job") throw new LuaWorkflowBuildError("max-turns-requires-job-tier", `"${id2}": ${m} is only legal on a tier:'job' agent step`);
|
|
8227
9363
|
if (!isWithinWorkflowJobRange(m, opts[m])) {
|
|
8228
9364
|
const { min, max } = WORKFLOW_JOB_RANGES[m];
|
|
8229
|
-
throw new LuaWorkflowBuildError("max-turns-invalid", `"${
|
|
9365
|
+
throw new LuaWorkflowBuildError("max-turns-invalid", `"${id2}": ${m} must be an integer ${min}..${max}`);
|
|
8230
9366
|
}
|
|
8231
9367
|
}
|
|
8232
9368
|
assertTimeout({
|
|
8233
|
-
id,
|
|
9369
|
+
id: id2,
|
|
8234
9370
|
timeoutSeconds: opts.timeoutSeconds,
|
|
8235
9371
|
tier,
|
|
8236
9372
|
workspace: opts.workspace,
|
|
8237
9373
|
kind: "agent"
|
|
8238
9374
|
});
|
|
8239
|
-
assertRetry(opts.retry,
|
|
9375
|
+
assertRetry(opts.retry, id2);
|
|
8240
9376
|
this.recordEnvRefs(opts.agentId, opts.prompt);
|
|
8241
9377
|
const node = defined({
|
|
8242
9378
|
type: "agent",
|
|
8243
|
-
id,
|
|
9379
|
+
id: id2,
|
|
8244
9380
|
agentId: opts.agentId,
|
|
8245
9381
|
promptTemplate: templateText(opts.prompt),
|
|
8246
9382
|
outputSchema: schemaToJson(opts.outputSchema),
|
|
@@ -8268,30 +9404,30 @@ var init_workflow = __esm({
|
|
|
8268
9404
|
node
|
|
8269
9405
|
});
|
|
8270
9406
|
}
|
|
8271
|
-
specialistStep(
|
|
8272
|
-
this.assertId(
|
|
9407
|
+
specialistStep(id2, opts) {
|
|
9408
|
+
this.assertId(id2, "specialistStep()");
|
|
8273
9409
|
const role = opts?.role;
|
|
8274
|
-
if (!role || typeof role !== "object") throw new LuaWorkflowBuildError("invalid-envelope", `specialistStep("${
|
|
9410
|
+
if (!role || typeof role !== "object") throw new LuaWorkflowBuildError("invalid-envelope", `specialistStep("${id2}") needs a role`);
|
|
8275
9411
|
if (role.ref !== void 0 && (role.name !== void 0 || role.instructions !== void 0 || role.tools !== void 0)) {
|
|
8276
|
-
throw new LuaWorkflowBuildError("role-ref-and-inline", `"${
|
|
9412
|
+
throw new LuaWorkflowBuildError("role-ref-and-inline", `"${id2}": role is EITHER { ref } OR the inline { name, instructions, tools } shape`);
|
|
8277
9413
|
}
|
|
8278
9414
|
if (role.ref === void 0) {
|
|
8279
9415
|
if (typeof role.instructions !== "string" || role.instructions.length > WORKFLOW_SPECIALIST_ROLE_MAX_INSTRUCTIONS) {
|
|
8280
|
-
throw new LuaWorkflowBuildError("ephemeral-role-too-long", `"${
|
|
9416
|
+
throw new LuaWorkflowBuildError("ephemeral-role-too-long", `"${id2}": role.instructions must be \u2264 ${WORKFLOW_SPECIALIST_ROLE_MAX_INSTRUCTIONS} chars`);
|
|
8281
9417
|
}
|
|
8282
|
-
if (!Array.isArray(role.tools)) throw new LuaWorkflowBuildError("invalid-envelope", `"${
|
|
8283
|
-
if (role.tools.length > 64) throw new LuaWorkflowBuildError("cap-exceeded", `"${
|
|
9418
|
+
if (!Array.isArray(role.tools)) throw new LuaWorkflowBuildError("invalid-envelope", `"${id2}": role.tools must be an array ([] = no tools)`);
|
|
9419
|
+
if (role.tools.length > 64) throw new LuaWorkflowBuildError("cap-exceeded", `"${id2}": role.tools exceeds 64 entries`);
|
|
8284
9420
|
}
|
|
8285
9421
|
assertTimeout({
|
|
8286
|
-
id,
|
|
9422
|
+
id: id2,
|
|
8287
9423
|
timeoutSeconds: opts.timeoutSeconds,
|
|
8288
9424
|
kind: "agent"
|
|
8289
9425
|
});
|
|
8290
|
-
assertRetry(opts.retry,
|
|
9426
|
+
assertRetry(opts.retry, id2);
|
|
8291
9427
|
this.recordEnvRefs(opts.prompt);
|
|
8292
9428
|
const node = defined({
|
|
8293
9429
|
type: "agent",
|
|
8294
|
-
id,
|
|
9430
|
+
id: id2,
|
|
8295
9431
|
agentId: "$self",
|
|
8296
9432
|
role: role.ref !== void 0 ? {
|
|
8297
9433
|
ref: role.ref
|
|
@@ -8314,20 +9450,20 @@ var init_workflow = __esm({
|
|
|
8314
9450
|
node
|
|
8315
9451
|
});
|
|
8316
9452
|
}
|
|
8317
|
-
toolStep(
|
|
8318
|
-
this.assertId(
|
|
8319
|
-
if (!tool || typeof tool !== "object" || typeof tool.name !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `toolStep("${
|
|
8320
|
-
assertNoClosure(opts.input, `toolStep("${
|
|
9453
|
+
toolStep(id2, tool, opts = {}) {
|
|
9454
|
+
this.assertId(id2, "toolStep()");
|
|
9455
|
+
if (!tool || typeof tool !== "object" || typeof tool.name !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `toolStep("${id2}") needs a LuaTool`);
|
|
9456
|
+
assertNoClosure(opts.input, `toolStep("${id2}").input`);
|
|
8321
9457
|
this.recordEnvRefs(opts.input);
|
|
8322
9458
|
assertTimeout({
|
|
8323
|
-
id,
|
|
9459
|
+
id: id2,
|
|
8324
9460
|
timeoutSeconds: opts.timeoutSeconds,
|
|
8325
9461
|
kind: "tool"
|
|
8326
9462
|
});
|
|
8327
|
-
assertRetry(opts.retry,
|
|
9463
|
+
assertRetry(opts.retry, id2);
|
|
8328
9464
|
const node = defined({
|
|
8329
9465
|
type: "tool",
|
|
8330
|
-
id,
|
|
9466
|
+
id: id2,
|
|
8331
9467
|
toolId: tool.name,
|
|
8332
9468
|
input: opts.input,
|
|
8333
9469
|
timeoutSeconds: opts.timeoutSeconds,
|
|
@@ -8341,34 +9477,34 @@ var init_workflow = __esm({
|
|
|
8341
9477
|
node
|
|
8342
9478
|
});
|
|
8343
9479
|
}
|
|
8344
|
-
approval(
|
|
8345
|
-
this.assertId(
|
|
8346
|
-
if (!opts || typeof opts.title !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `approval("${
|
|
9480
|
+
approval(id2, opts) {
|
|
9481
|
+
this.assertId(id2, "approval()");
|
|
9482
|
+
if (!opts || typeof opts.title !== "string") throw new LuaWorkflowBuildError("invalid-envelope", `approval("${id2}") needs a title`);
|
|
8347
9483
|
if (opts.approver === "creator" && opts.excludeInitiator === true) {
|
|
8348
|
-
throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${
|
|
9484
|
+
throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${id2}": approver:'creator' with excludeInitiator:true always excludes the only candidate`);
|
|
8349
9485
|
}
|
|
8350
9486
|
const editable = approvalEditable(opts);
|
|
8351
|
-
if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${
|
|
9487
|
+
if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id2}": \`fourEyes\` requires editable:true`);
|
|
8352
9488
|
if (opts.editable === false && Array.isArray(opts.editablePaths) && opts.editablePaths.length > 0) {
|
|
8353
|
-
throw new LuaWorkflowBuildError("editable-path-invalid", `"${
|
|
9489
|
+
throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": \`editablePaths\` beside editable:false is contradictory \u2014 drop the paths or set editable:true`);
|
|
8354
9490
|
} else if ((opts.editablePaths !== void 0 || opts.editedPayloadSchema !== void 0) && !editable) {
|
|
8355
|
-
throw new LuaWorkflowBuildError("editable-path-invalid", `"${
|
|
9491
|
+
throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": \`editablePaths\` / \`editedPayloadSchema\` require editable:true (a non-empty editablePaths implies it)`);
|
|
8356
9492
|
}
|
|
8357
9493
|
for (const p of opts.editablePaths ?? []) {
|
|
8358
|
-
if (!EDITABLE_PATH_RE2.test(p)) throw new LuaWorkflowBuildError("editable-path-invalid", `"${
|
|
9494
|
+
if (!EDITABLE_PATH_RE2.test(p)) throw new LuaWorkflowBuildError("editable-path-invalid", `"${id2}": editablePaths entry "${p}" is outside the grammar seg(.seg)* with [*]/[n] selectors`);
|
|
8359
9495
|
}
|
|
8360
9496
|
if (Array.isArray(opts.onTimeout)) {
|
|
8361
9497
|
const chain = opts.onTimeout;
|
|
8362
9498
|
const hops = chain.filter((h) => typeof h === "object");
|
|
8363
|
-
if (hops.length > 3) throw new LuaWorkflowBuildError("escalation-chain-too-long", `"${
|
|
9499
|
+
if (hops.length > 3) throw new LuaWorkflowBuildError("escalation-chain-too-long", `"${id2}": an onTimeout chain carries at most 3 escalation hops`);
|
|
8364
9500
|
const last = chain[chain.length - 1];
|
|
8365
|
-
if (last === void 0 || typeof last === "object") throw new LuaWorkflowBuildError("escalation-chain-not-terminal", `"${
|
|
9501
|
+
if (last === void 0 || typeof last === "object") throw new LuaWorkflowBuildError("escalation-chain-not-terminal", `"${id2}": an onTimeout chain must end in a terminal member`);
|
|
8366
9502
|
}
|
|
8367
|
-
if (typeof opts.details === "function") throw new LuaWorkflowBuildError("closure-binding", `approval("${
|
|
9503
|
+
if (typeof opts.details === "function") throw new LuaWorkflowBuildError("closure-binding", `approval("${id2}").details must be template(...)`);
|
|
8368
9504
|
this.recordEnvRefs(opts.details, opts.timeoutHours, opts.approver);
|
|
8369
9505
|
const node = defined({
|
|
8370
9506
|
type: "approval",
|
|
8371
|
-
id,
|
|
9507
|
+
id: id2,
|
|
8372
9508
|
title: opts.title,
|
|
8373
9509
|
details: opts.details ? templateText(opts.details) : void 0,
|
|
8374
9510
|
approver: opts.approver,
|
|
@@ -8390,13 +9526,13 @@ var init_workflow = __esm({
|
|
|
8390
9526
|
node
|
|
8391
9527
|
});
|
|
8392
9528
|
}
|
|
8393
|
-
waitForSignal(
|
|
8394
|
-
this.assertId(
|
|
8395
|
-
if (!opts || typeof opts.signal !== "string" || opts.signal.length === 0) throw new LuaWorkflowBuildError("invalid-envelope", `waitForSignal("${
|
|
9529
|
+
waitForSignal(id2, opts) {
|
|
9530
|
+
this.assertId(id2, "waitForSignal()");
|
|
9531
|
+
if (!opts || typeof opts.signal !== "string" || opts.signal.length === 0) throw new LuaWorkflowBuildError("invalid-envelope", `waitForSignal("${id2}") needs a signal name`);
|
|
8396
9532
|
this.recordEnvRefs(opts.timeoutHours);
|
|
8397
9533
|
const node = defined({
|
|
8398
9534
|
type: "waitForSignal",
|
|
8399
|
-
id,
|
|
9535
|
+
id: id2,
|
|
8400
9536
|
signal: opts.signal,
|
|
8401
9537
|
schema: schemaToJson(opts.schema),
|
|
8402
9538
|
timeoutHours: opts.timeoutHours,
|
|
@@ -8409,28 +9545,28 @@ var init_workflow = __esm({
|
|
|
8409
9545
|
node
|
|
8410
9546
|
});
|
|
8411
9547
|
}
|
|
8412
|
-
workflow(
|
|
8413
|
-
this.assertId(
|
|
8414
|
-
assertRetry(opts?.retry,
|
|
9548
|
+
workflow(id2, ref, input, opts) {
|
|
9549
|
+
this.assertId(id2, "workflow()");
|
|
9550
|
+
assertRetry(opts?.retry, id2);
|
|
8415
9551
|
const name = typeof ref === "string" ? ref : ref instanceof LuaWorkflow ? ref.getName() : void 0;
|
|
8416
|
-
if (!name) throw new LuaWorkflowBuildError("invalid-envelope", `workflow("${
|
|
9552
|
+
if (!name) throw new LuaWorkflowBuildError("invalid-envelope", `workflow("${id2}") needs a LuaWorkflow or a workflow name`);
|
|
8417
9553
|
if (opts?.workspace === "inherit") {
|
|
8418
|
-
if (!this.config.workspace) throw new LuaWorkflowBuildError("workspace-inherit-without-parent-workspace", `"${
|
|
8419
|
-
if (ref instanceof LuaWorkflow && ref.getConfig().workspace) throw new LuaWorkflowBuildError("workspace-inherit-conflict", `"${
|
|
9554
|
+
if (!this.config.workspace) throw new LuaWorkflowBuildError("workspace-inherit-without-parent-workspace", `"${id2}": workspace:'inherit' but the parent createWorkflow declares no workspace`);
|
|
9555
|
+
if (ref instanceof LuaWorkflow && ref.getConfig().workspace) throw new LuaWorkflowBuildError("workspace-inherit-conflict", `"${id2}": workspace:'inherit' on a workflow that declares its own workspace`);
|
|
8420
9556
|
}
|
|
8421
|
-
assertNoClosure(input, `workflow("${
|
|
9557
|
+
assertNoClosure(input, `workflow("${id2}").input`);
|
|
8422
9558
|
this.recordEnvRefs(input);
|
|
8423
9559
|
this.nestedRefs.push(opts?.workspace === "inherit" ? {
|
|
8424
|
-
id,
|
|
9560
|
+
id: id2,
|
|
8425
9561
|
name,
|
|
8426
9562
|
workspace: "inherit"
|
|
8427
9563
|
} : {
|
|
8428
|
-
id,
|
|
9564
|
+
id: id2,
|
|
8429
9565
|
name
|
|
8430
9566
|
});
|
|
8431
9567
|
const node = defined({
|
|
8432
9568
|
type: "workflow",
|
|
8433
|
-
id,
|
|
9569
|
+
id: id2,
|
|
8434
9570
|
workflowId: name,
|
|
8435
9571
|
input,
|
|
8436
9572
|
workspace: opts?.workspace,
|
|
@@ -8509,8 +9645,8 @@ var init_workflow = __esm({
|
|
|
8509
9645
|
});
|
|
8510
9646
|
}
|
|
8511
9647
|
}
|
|
8512
|
-
assertId(
|
|
8513
|
-
if (typeof
|
|
9648
|
+
assertId(id2, where) {
|
|
9649
|
+
if (typeof id2 !== "string" || !STEP_ID_RE.test(id2)) throw new LuaWorkflowBuildError("invalid-step-id", `${where}: id "${String(id2)}" must match ${STEP_ID_RE}`);
|
|
8514
9650
|
}
|
|
8515
9651
|
};
|
|
8516
9652
|
EDITABLE_PATH_RE2 = /^[A-Za-z_][A-Za-z0-9_]*(\[(\*|\d+)\])?(\.[A-Za-z_][A-Za-z0-9_]*(\[(\*|\d+)\])?)*$/;
|
|
@@ -8688,7 +9824,7 @@ var init_lua_fetch = __esm({
|
|
|
8688
9824
|
});
|
|
8689
9825
|
|
|
8690
9826
|
// src/services/firebase-session.ts
|
|
8691
|
-
import { z as
|
|
9827
|
+
import { z as z6 } from "zod";
|
|
8692
9828
|
function rejectedRefreshReason(message) {
|
|
8693
9829
|
const normalised = message.toUpperCase();
|
|
8694
9830
|
return REJECTED_REFRESH_REASONS.find((reason) => normalised.includes(reason));
|
|
@@ -8834,20 +9970,20 @@ var init_firebase_session = __esm({
|
|
|
8834
9970
|
this.name = "FirebaseSessionRejectedError";
|
|
8835
9971
|
}
|
|
8836
9972
|
};
|
|
8837
|
-
customTokenResponseSchema =
|
|
8838
|
-
idToken:
|
|
8839
|
-
refreshToken:
|
|
8840
|
-
expiresIn:
|
|
8841
|
-
localId:
|
|
9973
|
+
customTokenResponseSchema = z6.object({
|
|
9974
|
+
idToken: z6.string().min(1),
|
|
9975
|
+
refreshToken: z6.string().min(1),
|
|
9976
|
+
expiresIn: z6.coerce.number().positive().finite(),
|
|
9977
|
+
localId: z6.string().min(1).optional()
|
|
8842
9978
|
});
|
|
8843
|
-
refreshResponseSchema =
|
|
8844
|
-
id_token:
|
|
8845
|
-
refresh_token:
|
|
8846
|
-
expires_in:
|
|
8847
|
-
user_id:
|
|
9979
|
+
refreshResponseSchema = z6.object({
|
|
9980
|
+
id_token: z6.string().min(1),
|
|
9981
|
+
refresh_token: z6.string().min(1),
|
|
9982
|
+
expires_in: z6.coerce.number().positive().finite(),
|
|
9983
|
+
user_id: z6.string().min(1)
|
|
8848
9984
|
});
|
|
8849
|
-
firebaseIdTokenPayloadSchema =
|
|
8850
|
-
sub:
|
|
9985
|
+
firebaseIdTokenPayloadSchema = z6.object({
|
|
9986
|
+
sub: z6.string().min(1)
|
|
8851
9987
|
});
|
|
8852
9988
|
__name(requireFirebaseWebApiKey, "requireFirebaseWebApiKey");
|
|
8853
9989
|
__name(claimsOfFirebaseIdToken, "claimsOfFirebaseIdToken");
|
|
@@ -8864,7 +10000,7 @@ var init_firebase_session = __esm({
|
|
|
8864
10000
|
import { createHash as createHash3, randomUUID } from "crypto";
|
|
8865
10001
|
import { mkdir, open, readFile, rename, rm, stat, unlink, writeFile } from "fs/promises";
|
|
8866
10002
|
import { join as join3 } from "path";
|
|
8867
|
-
import { z as
|
|
10003
|
+
import { z as z7 } from "zod";
|
|
8868
10004
|
function environmentKey(environment) {
|
|
8869
10005
|
return createHash3("sha256").update(`${environment.apiUrl}
|
|
8870
10006
|
${environment.authUrl}
|
|
@@ -8881,15 +10017,15 @@ var init_firebase_session_store = __esm({
|
|
|
8881
10017
|
"src/services/firebase-session-store.ts"() {
|
|
8882
10018
|
"use strict";
|
|
8883
10019
|
init_constants();
|
|
8884
|
-
storedFirebaseSessionSchema =
|
|
8885
|
-
version:
|
|
8886
|
-
kind:
|
|
8887
|
-
generation:
|
|
8888
|
-
refreshToken:
|
|
8889
|
-
firebaseUid:
|
|
8890
|
-
apiUrl:
|
|
8891
|
-
authUrl:
|
|
8892
|
-
firebaseWebApiKey:
|
|
10020
|
+
storedFirebaseSessionSchema = z7.object({
|
|
10021
|
+
version: z7.literal(1),
|
|
10022
|
+
kind: z7.literal("firebase-session"),
|
|
10023
|
+
generation: z7.string().min(1),
|
|
10024
|
+
refreshToken: z7.string().min(1),
|
|
10025
|
+
firebaseUid: z7.string().min(1),
|
|
10026
|
+
apiUrl: z7.string().url(),
|
|
10027
|
+
authUrl: z7.string().url(),
|
|
10028
|
+
firebaseWebApiKey: z7.string().min(1)
|
|
8893
10029
|
});
|
|
8894
10030
|
currentFirebaseSessionEnvironment = /* @__PURE__ */ __name(() => ({
|
|
8895
10031
|
apiUrl: BASE_URLS.API,
|
|
@@ -9560,7 +10696,7 @@ async function* parseSseStream(body, signal) {
|
|
|
9560
10696
|
const decoder = new TextDecoder();
|
|
9561
10697
|
let buffer = "";
|
|
9562
10698
|
const flush = /* @__PURE__ */ __name((block) => {
|
|
9563
|
-
let
|
|
10699
|
+
let id2;
|
|
9564
10700
|
let event = "message";
|
|
9565
10701
|
const data = [];
|
|
9566
10702
|
for (const rawLine of block.split("\n")) {
|
|
@@ -9570,11 +10706,11 @@ async function* parseSseStream(body, signal) {
|
|
|
9570
10706
|
const field = colon === -1 ? line : line.slice(0, colon);
|
|
9571
10707
|
let value3 = colon === -1 ? "" : line.slice(colon + 1);
|
|
9572
10708
|
if (value3.startsWith(" ")) value3 = value3.slice(1);
|
|
9573
|
-
if (field === "id")
|
|
10709
|
+
if (field === "id") id2 = value3;
|
|
9574
10710
|
else if (field === "event") event = value3;
|
|
9575
10711
|
else if (field === "data") data.push(value3);
|
|
9576
10712
|
}
|
|
9577
|
-
if (data.length === 0 &&
|
|
10713
|
+
if (data.length === 0 && id2 === void 0 && event === "message") return void 0;
|
|
9578
10714
|
const joined = data.join("\n");
|
|
9579
10715
|
let parsed = joined;
|
|
9580
10716
|
try {
|
|
@@ -9583,7 +10719,7 @@ async function* parseSseStream(body, signal) {
|
|
|
9583
10719
|
parsed = joined;
|
|
9584
10720
|
}
|
|
9585
10721
|
return {
|
|
9586
|
-
id,
|
|
10722
|
+
id: id2,
|
|
9587
10723
|
event,
|
|
9588
10724
|
data: parsed
|
|
9589
10725
|
};
|
|
@@ -10975,11 +12111,17 @@ var init_base_handler = __esm({
|
|
|
10975
12111
|
/**
|
|
10976
12112
|
* Phase 2 of parallel sync: apply fetched data to YAML.
|
|
10977
12113
|
* Optionally creates missing primitives on server if apiKey+agentId provided.
|
|
12114
|
+
*
|
|
12115
|
+
* PRO-2150 — `apiCredentials.registerOnly` drops the two writes that overwrite what the developer
|
|
12116
|
+
* pinned (the server-only orphan stubs in Part 1, and the version reconciliation half of Part 2)
|
|
12117
|
+
* while keeping id linking and create-on-server. `lua chat` uses it: it needs the skills'/processors'
|
|
12118
|
+
* server ids to exist before the sandbox push, and nothing else.
|
|
10978
12119
|
*/
|
|
10979
12120
|
async applySyncToYaml(serverData, config, manifest, apiCredentials) {
|
|
10980
12121
|
const messages = [];
|
|
10981
12122
|
let yamlUpdated = false;
|
|
10982
12123
|
let orphanedCount = 0;
|
|
12124
|
+
const registerOnly = apiCredentials?.registerOnly === true;
|
|
10983
12125
|
try {
|
|
10984
12126
|
if (!serverData.serverItems) {
|
|
10985
12127
|
if (serverData.fetchError) {
|
|
@@ -11007,10 +12149,10 @@ var init_base_handler = __esm({
|
|
|
11007
12149
|
messages.push(msg);
|
|
11008
12150
|
console.log(msg);
|
|
11009
12151
|
}
|
|
11010
|
-
const orphans = serverData.serverItems.filter((item) => {
|
|
11011
|
-
const
|
|
12152
|
+
const orphans = registerOnly ? [] : serverData.serverItems.filter((item) => {
|
|
12153
|
+
const id2 = item.id;
|
|
11012
12154
|
const name = item.name;
|
|
11013
|
-
return !yamlById.has(
|
|
12155
|
+
return !yamlById.has(id2) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);
|
|
11014
12156
|
});
|
|
11015
12157
|
if (orphans.length > 0) {
|
|
11016
12158
|
const stubs = orphans.map((item) => this.cleanItem({
|
|
@@ -11034,7 +12176,9 @@ var init_base_handler = __esm({
|
|
|
11034
12176
|
`);
|
|
11035
12177
|
orphanedCount = orphans.length;
|
|
11036
12178
|
}
|
|
11037
|
-
const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName
|
|
12179
|
+
const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName, {
|
|
12180
|
+
syncVersions: !registerOnly
|
|
12181
|
+
});
|
|
11038
12182
|
messages.push(...msgs);
|
|
11039
12183
|
if (changed) {
|
|
11040
12184
|
yamlUpdated = true;
|
|
@@ -11226,7 +12370,7 @@ var init_base_handler = __esm({
|
|
|
11226
12370
|
const result = /* @__PURE__ */ new Map();
|
|
11227
12371
|
const { serverItems } = await this.fetchServerState(apiKey, agentId);
|
|
11228
12372
|
if (!serverItems) {
|
|
11229
|
-
entityIds.forEach((
|
|
12373
|
+
entityIds.forEach((id2) => result.set(id2, null));
|
|
11230
12374
|
return result;
|
|
11231
12375
|
}
|
|
11232
12376
|
for (const entityId of entityIds) {
|
|
@@ -11260,8 +12404,8 @@ var init_base_handler = __esm({
|
|
|
11260
12404
|
const yamlById = /* @__PURE__ */ new Map();
|
|
11261
12405
|
const yamlByName = /* @__PURE__ */ new Map();
|
|
11262
12406
|
for (const item of yamlItems) {
|
|
11263
|
-
const
|
|
11264
|
-
if (
|
|
12407
|
+
const id2 = this.getItemId(item);
|
|
12408
|
+
if (id2) yamlById.set(id2, item);
|
|
11265
12409
|
yamlByName.set(item.name, item);
|
|
11266
12410
|
}
|
|
11267
12411
|
const serverByName = /* @__PURE__ */ new Map();
|
|
@@ -11277,7 +12421,8 @@ var init_base_handler = __esm({
|
|
|
11277
12421
|
/**
|
|
11278
12422
|
* For each YAML item, match to server by name, populate missing IDs, update versions.
|
|
11279
12423
|
*/
|
|
11280
|
-
syncFromServer(yamlItems, serverByName) {
|
|
12424
|
+
syncFromServer(yamlItems, serverByName, options) {
|
|
12425
|
+
const syncVersions = options?.syncVersions !== false;
|
|
11281
12426
|
const msgs = [];
|
|
11282
12427
|
let changed = false;
|
|
11283
12428
|
const idField = this.yamlConfig.idField;
|
|
@@ -11298,7 +12443,7 @@ var init_base_handler = __esm({
|
|
|
11298
12443
|
};
|
|
11299
12444
|
}
|
|
11300
12445
|
const versions = serverItem.versions;
|
|
11301
|
-
if (Array.isArray(versions) && versions.length > 0) {
|
|
12446
|
+
if (syncVersions && Array.isArray(versions) && versions.length > 0) {
|
|
11302
12447
|
const activeVersion = this.getActiveVersion(serverItem);
|
|
11303
12448
|
const currentVersion = item.version;
|
|
11304
12449
|
if (activeVersion && activeVersion !== currentVersion) {
|
|
@@ -15123,7 +16268,7 @@ var init_workflow_api_service = __esm({
|
|
|
15123
16268
|
throw new WorkflowApiError("FORBIDDEN", `Workflows.${member}: goals are scoped to the bound agent ${api.agentId}`, 403);
|
|
15124
16269
|
}
|
|
15125
16270
|
}, "assertBoundAgent");
|
|
15126
|
-
pathId = /* @__PURE__ */ __name((
|
|
16271
|
+
pathId = /* @__PURE__ */ __name((id2) => encodeURIComponent(id2), "pathId");
|
|
15127
16272
|
unavailable = /* @__PURE__ */ __name((member, route) => async () => {
|
|
15128
16273
|
throw new WorkflowApiError("WORKFLOWS_API_UNAVAILABLE", `Workflows.${member} is not available in this runtime yet (${route} lands with a later wave)`, 501);
|
|
15129
16274
|
}, "unavailable");
|
|
@@ -15859,6 +17004,20 @@ var env = Object.assign((key, _opts) => readEnv(key), {
|
|
|
15859
17004
|
};
|
|
15860
17005
|
}, "template")
|
|
15861
17006
|
});
|
|
17007
|
+
var log = Object.freeze({
|
|
17008
|
+
debug: /* @__PURE__ */ __name((message, fields) => emitLocalLog("debug", message, fields), "debug"),
|
|
17009
|
+
info: /* @__PURE__ */ __name((message, fields) => emitLocalLog("info", message, fields), "info"),
|
|
17010
|
+
warn: /* @__PURE__ */ __name((message, fields) => emitLocalLog("warn", message, fields), "warn"),
|
|
17011
|
+
error: /* @__PURE__ */ __name((message, fields) => emitLocalLog("error", message, fields), "error")
|
|
17012
|
+
});
|
|
17013
|
+
function emitLocalLog(level, message, fields) {
|
|
17014
|
+
const normalized = normalizeLogFields(fields);
|
|
17015
|
+
const text = typeof message === "object" && message !== null ? JSON.stringify(message) : String(message);
|
|
17016
|
+
const write = level === "error" ? console.error : level === "warn" ? console.warn : level === "info" ? console.info : console.debug;
|
|
17017
|
+
if (normalized) write(text, JSON.stringify(normalized));
|
|
17018
|
+
else write(text);
|
|
17019
|
+
}
|
|
17020
|
+
__name(emitLocalLog, "emitLocalLog");
|
|
15862
17021
|
var ToolFlag = /* @__PURE__ */ (function(ToolFlag2) {
|
|
15863
17022
|
ToolFlag2["NONE"] = "none";
|
|
15864
17023
|
ToolFlag2["IGNORE_ON_ENTER"] = "ignore_on_enter";
|
|
@@ -16819,9 +17978,9 @@ var Products = {
|
|
|
16819
17978
|
* @param id - Product ID
|
|
16820
17979
|
* @returns Promise resolving when deletion is complete
|
|
16821
17980
|
*/
|
|
16822
|
-
async delete(
|
|
17981
|
+
async delete(id2) {
|
|
16823
17982
|
const instance = await getProductsInstance();
|
|
16824
|
-
return instance.delete(
|
|
17983
|
+
return instance.delete(id2);
|
|
16825
17984
|
},
|
|
16826
17985
|
/**
|
|
16827
17986
|
* Searches products by query string.
|
|
@@ -16839,9 +17998,9 @@ var Products = {
|
|
|
16839
17998
|
* @param id - Product ID
|
|
16840
17999
|
* @returns Promise resolving to product data
|
|
16841
18000
|
*/
|
|
16842
|
-
async getById(
|
|
18001
|
+
async getById(id2) {
|
|
16843
18002
|
const instance = await getProductsInstance();
|
|
16844
|
-
return instance.getById(
|
|
18003
|
+
return instance.getById(id2);
|
|
16845
18004
|
}
|
|
16846
18005
|
};
|
|
16847
18006
|
var Baskets = {
|
|
@@ -17378,6 +18537,7 @@ export {
|
|
|
17378
18537
|
inSet2 as inSet,
|
|
17379
18538
|
init2 as init,
|
|
17380
18539
|
lit2 as lit,
|
|
18540
|
+
log,
|
|
17381
18541
|
lt2 as lt,
|
|
17382
18542
|
lte2 as lte,
|
|
17383
18543
|
ne2 as ne,
|