@runtypelabs/cli 2.19.1 → 2.19.2
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/index.js +3236 -21
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -15164,7 +15164,7 @@ var apiRoutingDocSchema = external_exports.object({
|
|
|
15164
15164
|
path: ["api", "activeScript"]
|
|
15165
15165
|
});
|
|
15166
15166
|
|
|
15167
|
-
// ../shared/dist/chunk-
|
|
15167
|
+
// ../shared/dist/chunk-7Y2SRVP7.mjs
|
|
15168
15168
|
function getNestedValue(obj, path18) {
|
|
15169
15169
|
let normalizedPath = path18;
|
|
15170
15170
|
normalizedPath = normalizedPath.replace(/^\$\.?/, "");
|
|
@@ -15207,6 +15207,14 @@ var SYSTEM_VARIABLES = /* @__PURE__ */ new Set([
|
|
|
15207
15207
|
"_record",
|
|
15208
15208
|
"_now",
|
|
15209
15209
|
"_schedule",
|
|
15210
|
+
// `_tools` is engine-populated, but LATER than the other system vars: it is
|
|
15211
|
+
// injected after tool resolution, just before dispatch (see
|
|
15212
|
+
// `injectToolsSystemVariable` in the api prompt-executor), so a prompt may
|
|
15213
|
+
// reference `{{_tools.interfaces}}` / `{{_tools.count}}` / `{{_tools.names}}`.
|
|
15214
|
+
// It belongs to the system namespace so the validator / FPO gate don't flag
|
|
15215
|
+
// it as undeclared and the executors don't report it as "unresolved" before
|
|
15216
|
+
// injection runs.
|
|
15217
|
+
"_tools",
|
|
15210
15218
|
"messages",
|
|
15211
15219
|
"userMessage",
|
|
15212
15220
|
"lastMessage",
|
|
@@ -15355,6 +15363,18 @@ function stringifyValue(value) {
|
|
|
15355
15363
|
if (typeof value === "object") return JSON.stringify(value);
|
|
15356
15364
|
return String(value);
|
|
15357
15365
|
}
|
|
15366
|
+
function extractTemplateExpressionPaths(expr) {
|
|
15367
|
+
let parsed;
|
|
15368
|
+
try {
|
|
15369
|
+
parsed = parseTemplateExpression(expr);
|
|
15370
|
+
} catch {
|
|
15371
|
+
return [];
|
|
15372
|
+
}
|
|
15373
|
+
if (parsed.kind === "legacy") {
|
|
15374
|
+
return parsed.variable ? [parsed.variable] : [];
|
|
15375
|
+
}
|
|
15376
|
+
return parsed.operands.filter((o) => o.kind === "path").map((o) => o.path);
|
|
15377
|
+
}
|
|
15358
15378
|
var _SimpleTemplateEngine = class _SimpleTemplateEngine2 {
|
|
15359
15379
|
substitute(template, context = {}) {
|
|
15360
15380
|
const usedVariables = [];
|
|
@@ -15986,7 +16006,15 @@ var stepCompleteEventSchema = external_exports.object({
|
|
|
15986
16006
|
stopReason: wireStopReasonSchema.optional(),
|
|
15987
16007
|
stepId: external_exports.string().optional(),
|
|
15988
16008
|
stepName: external_exports.string().optional(),
|
|
15989
|
-
toolContext: toolContextSchema.optional()
|
|
16009
|
+
toolContext: toolContextSchema.optional(),
|
|
16010
|
+
// Template variables that were still unresolved (`{{...}}` left intact) when
|
|
16011
|
+
// the prompt was dispatched to the model — the catch-all observability signal
|
|
16012
|
+
// for a surviving token (a missing flow input, an undeclared variable, or an
|
|
16013
|
+
// unknown-namespace typo). Only prompt steps populate it, and only when
|
|
16014
|
+
// non-empty; absence means every reference resolved. Non-fatal: the step still
|
|
16015
|
+
// ran. Sourced from the template engine's `missingVariables`, which already
|
|
16016
|
+
// includes unknown-namespace tokens (see `TemplateSubstitutionResult`).
|
|
16017
|
+
unresolvedVariables: external_exports.array(external_exports.string()).optional()
|
|
15990
16018
|
});
|
|
15991
16019
|
var stepErrorEventSchema = external_exports.object({
|
|
15992
16020
|
...baseFlowEvent,
|
|
@@ -16441,6 +16469,79 @@ var ExecuteToolSchema = external_exports.object({
|
|
|
16441
16469
|
userId: external_exports.string()
|
|
16442
16470
|
}).optional()
|
|
16443
16471
|
});
|
|
16472
|
+
function parseToolInstanceId(toolId) {
|
|
16473
|
+
const hashIndex = toolId.indexOf("#");
|
|
16474
|
+
if (hashIndex === -1) {
|
|
16475
|
+
return { baseId: toolId, instanceId: "" };
|
|
16476
|
+
}
|
|
16477
|
+
return {
|
|
16478
|
+
baseId: toolId.substring(0, hashIndex),
|
|
16479
|
+
instanceId: toolId.substring(hashIndex + 1)
|
|
16480
|
+
};
|
|
16481
|
+
}
|
|
16482
|
+
function isBuiltInToolId(toolId) {
|
|
16483
|
+
return toolId.startsWith("builtin:");
|
|
16484
|
+
}
|
|
16485
|
+
function isPlatformToolId(toolId) {
|
|
16486
|
+
return toolId.startsWith("platform:");
|
|
16487
|
+
}
|
|
16488
|
+
var INTEGRATION_SERVER_IDS = /* @__PURE__ */ new Set(["slack", "google", "linear", "github", "telegram"]);
|
|
16489
|
+
function isBuiltInIntegrationToolId(toolId) {
|
|
16490
|
+
if (!toolId.startsWith("builtin:")) return false;
|
|
16491
|
+
const { baseId } = parseToolInstanceId(toolId);
|
|
16492
|
+
const parts = baseId.split(":");
|
|
16493
|
+
if (parts.length < 3) return false;
|
|
16494
|
+
return INTEGRATION_SERVER_IDS.has(parts[1]);
|
|
16495
|
+
}
|
|
16496
|
+
function isMCPToolId(toolId) {
|
|
16497
|
+
return toolId.startsWith("mcp:");
|
|
16498
|
+
}
|
|
16499
|
+
var NAMED_TOOL_REF_PREFIX = "tool:";
|
|
16500
|
+
function isNamedToolRef(toolId) {
|
|
16501
|
+
return toolId.startsWith(NAMED_TOOL_REF_PREFIX) && toolId.length > NAMED_TOOL_REF_PREFIX.length;
|
|
16502
|
+
}
|
|
16503
|
+
function parseNamedToolRef(toolId) {
|
|
16504
|
+
if (!isNamedToolRef(toolId)) return null;
|
|
16505
|
+
return { name: toolId.slice(NAMED_TOOL_REF_PREFIX.length) };
|
|
16506
|
+
}
|
|
16507
|
+
function separateToolIds(toolIds) {
|
|
16508
|
+
const builtInToolIds = [];
|
|
16509
|
+
const platformToolIds = [];
|
|
16510
|
+
const integrationToolIds = [];
|
|
16511
|
+
const mcpToolIds = [];
|
|
16512
|
+
const dataConnectionToolIds = [];
|
|
16513
|
+
const namedToolIds = [];
|
|
16514
|
+
const customToolIds = [];
|
|
16515
|
+
for (const toolId of toolIds) {
|
|
16516
|
+
if (isDataConnectionToolId(toolId)) {
|
|
16517
|
+
dataConnectionToolIds.push(toolId);
|
|
16518
|
+
} else if (isPlatformToolId(toolId)) {
|
|
16519
|
+
platformToolIds.push(toolId);
|
|
16520
|
+
} else if (isBuiltInIntegrationToolId(toolId)) {
|
|
16521
|
+
integrationToolIds.push(toolId);
|
|
16522
|
+
} else if (isBuiltInToolId(toolId)) {
|
|
16523
|
+
builtInToolIds.push(toolId);
|
|
16524
|
+
} else if (isMCPToolId(toolId)) {
|
|
16525
|
+
mcpToolIds.push(toolId);
|
|
16526
|
+
} else if (isNamedToolRef(toolId)) {
|
|
16527
|
+
namedToolIds.push(toolId);
|
|
16528
|
+
} else {
|
|
16529
|
+
customToolIds.push(toolId);
|
|
16530
|
+
}
|
|
16531
|
+
}
|
|
16532
|
+
return {
|
|
16533
|
+
builtInToolIds,
|
|
16534
|
+
platformToolIds,
|
|
16535
|
+
integrationToolIds,
|
|
16536
|
+
mcpToolIds,
|
|
16537
|
+
dataConnectionToolIds,
|
|
16538
|
+
namedToolIds,
|
|
16539
|
+
customToolIds
|
|
16540
|
+
};
|
|
16541
|
+
}
|
|
16542
|
+
function isDataConnectionToolId(toolId) {
|
|
16543
|
+
return toolId.startsWith("dc:");
|
|
16544
|
+
}
|
|
16444
16545
|
var contextFallbackSchema = external_exports.union([
|
|
16445
16546
|
external_exports.object({ type: external_exports.literal("retry"), delay: external_exports.number().optional() }),
|
|
16446
16547
|
external_exports.object({
|
|
@@ -17247,6 +17348,1923 @@ var CONTEXT_STEP_TYPES = [
|
|
|
17247
17348
|
"memory-summary"
|
|
17248
17349
|
];
|
|
17249
17350
|
var FLOW_STEP_TYPES = ["prompt", ...CONTEXT_STEP_TYPES];
|
|
17351
|
+
var DEFAULT_MANAGED_SEND_FROM_DOMAIN = "runtype.email";
|
|
17352
|
+
var STAGING_MANAGED_SEND_FROM_DOMAIN = "runtype-staging.email";
|
|
17353
|
+
var MANAGED_SEND_FROM_DOMAINS = [
|
|
17354
|
+
DEFAULT_MANAGED_SEND_FROM_DOMAIN,
|
|
17355
|
+
STAGING_MANAGED_SEND_FROM_DOMAIN
|
|
17356
|
+
];
|
|
17357
|
+
var MANAGED_TEMPLATE_SEND_FROM_ADDRESS_REGEX = /^{{\s*_flow\.id\s*}}@([^@\s]+)$/i;
|
|
17358
|
+
var LEGACY_MANAGED_SEND_FROM_ADDRESS_REGEX = /^[^@\s]+@messages\.runtype\.(com|ai)$/i;
|
|
17359
|
+
function normalizeFromAddress(configuredFrom) {
|
|
17360
|
+
return configuredFrom?.trim() ?? "";
|
|
17361
|
+
}
|
|
17362
|
+
function normalizeDomain(domain2) {
|
|
17363
|
+
return domain2?.trim().toLowerCase() ?? "";
|
|
17364
|
+
}
|
|
17365
|
+
function extractDomainFromAddress(fromAddress) {
|
|
17366
|
+
const normalizedFrom = normalizeFromAddress(fromAddress);
|
|
17367
|
+
const atIndex = normalizedFrom.lastIndexOf("@");
|
|
17368
|
+
if (atIndex === -1) {
|
|
17369
|
+
return void 0;
|
|
17370
|
+
}
|
|
17371
|
+
const domain2 = normalizedFrom.slice(atIndex + 1);
|
|
17372
|
+
return normalizeDomain(domain2) || void 0;
|
|
17373
|
+
}
|
|
17374
|
+
function getReservedManagedSendFromDomains(preferredManagedDomain) {
|
|
17375
|
+
const preferredDomain = normalizeDomain(preferredManagedDomain);
|
|
17376
|
+
const reservedDomains = preferredDomain ? [preferredDomain, ...MANAGED_SEND_FROM_DOMAINS] : [...MANAGED_SEND_FROM_DOMAINS];
|
|
17377
|
+
return Array.from(new Set(reservedDomains));
|
|
17378
|
+
}
|
|
17379
|
+
function isReservedManagedSendFromDomain(domain2, preferredManagedDomain) {
|
|
17380
|
+
const normalizedDomain = normalizeDomain(domain2);
|
|
17381
|
+
if (!normalizedDomain) {
|
|
17382
|
+
return false;
|
|
17383
|
+
}
|
|
17384
|
+
return getReservedManagedSendFromDomains(preferredManagedDomain).includes(normalizedDomain);
|
|
17385
|
+
}
|
|
17386
|
+
function extractManagedTemplateDomain(configuredFrom) {
|
|
17387
|
+
const normalizedFrom = normalizeFromAddress(configuredFrom);
|
|
17388
|
+
const managedTemplateMatch = normalizedFrom.match(MANAGED_TEMPLATE_SEND_FROM_ADDRESS_REGEX);
|
|
17389
|
+
return normalizeDomain(managedTemplateMatch?.[1]) || void 0;
|
|
17390
|
+
}
|
|
17391
|
+
function isManagedTemplateSendFromAddress(configuredFrom, preferredManagedDomain) {
|
|
17392
|
+
return isReservedManagedSendFromDomain(
|
|
17393
|
+
extractManagedTemplateDomain(configuredFrom),
|
|
17394
|
+
preferredManagedDomain
|
|
17395
|
+
);
|
|
17396
|
+
}
|
|
17397
|
+
function isLegacyManagedSendFromAddress(configuredFrom) {
|
|
17398
|
+
return LEGACY_MANAGED_SEND_FROM_ADDRESS_REGEX.test(normalizeFromAddress(configuredFrom));
|
|
17399
|
+
}
|
|
17400
|
+
function shouldUseManagedSendFromAddress(configuredFrom, preferredManagedDomain) {
|
|
17401
|
+
if (!normalizeFromAddress(configuredFrom)) {
|
|
17402
|
+
return true;
|
|
17403
|
+
}
|
|
17404
|
+
return isManagedTemplateSendFromAddress(configuredFrom, preferredManagedDomain) || isLegacyManagedSendFromAddress(configuredFrom);
|
|
17405
|
+
}
|
|
17406
|
+
function isCustomSendFromAddressOnManagedDomain(configuredFrom, preferredManagedDomain) {
|
|
17407
|
+
if (shouldUseManagedSendFromAddress(configuredFrom, preferredManagedDomain)) {
|
|
17408
|
+
return false;
|
|
17409
|
+
}
|
|
17410
|
+
return isReservedManagedSendFromDomain(
|
|
17411
|
+
extractDomainFromAddress(configuredFrom),
|
|
17412
|
+
preferredManagedDomain
|
|
17413
|
+
);
|
|
17414
|
+
}
|
|
17415
|
+
var NormalizationError = class extends Error {
|
|
17416
|
+
constructor(message, stepType, fieldName, expectedType, actualValue) {
|
|
17417
|
+
super(message);
|
|
17418
|
+
this.stepType = stepType;
|
|
17419
|
+
this.fieldName = fieldName;
|
|
17420
|
+
this.expectedType = expectedType;
|
|
17421
|
+
this.actualValue = actualValue;
|
|
17422
|
+
this.name = "NormalizationError";
|
|
17423
|
+
}
|
|
17424
|
+
};
|
|
17425
|
+
function validateRequired(value, fieldName, stepType) {
|
|
17426
|
+
if (value === null || value === void 0 || value === "") {
|
|
17427
|
+
throw new NormalizationError(
|
|
17428
|
+
`Missing required field '${fieldName}' for ${stepType} step`,
|
|
17429
|
+
stepType,
|
|
17430
|
+
fieldName,
|
|
17431
|
+
"non-null value",
|
|
17432
|
+
value
|
|
17433
|
+
);
|
|
17434
|
+
}
|
|
17435
|
+
}
|
|
17436
|
+
function validateString(value, fieldName, stepType, required2 = false) {
|
|
17437
|
+
if (required2) {
|
|
17438
|
+
validateRequired(value, fieldName, stepType);
|
|
17439
|
+
}
|
|
17440
|
+
if (value !== void 0 && value !== null && typeof value !== "string") {
|
|
17441
|
+
throw new NormalizationError(
|
|
17442
|
+
`Field '${fieldName}' must be a string for ${stepType} step`,
|
|
17443
|
+
stepType,
|
|
17444
|
+
fieldName,
|
|
17445
|
+
"string",
|
|
17446
|
+
typeof value
|
|
17447
|
+
);
|
|
17448
|
+
}
|
|
17449
|
+
}
|
|
17450
|
+
function validateNumber(value, fieldName, stepType, required2 = false) {
|
|
17451
|
+
if (required2) {
|
|
17452
|
+
validateRequired(value, fieldName, stepType);
|
|
17453
|
+
}
|
|
17454
|
+
if (value !== void 0 && value !== null) {
|
|
17455
|
+
const num = Number(value);
|
|
17456
|
+
if (isNaN(num)) {
|
|
17457
|
+
throw new NormalizationError(
|
|
17458
|
+
`Field '${fieldName}' must be a number for ${stepType} step`,
|
|
17459
|
+
stepType,
|
|
17460
|
+
fieldName,
|
|
17461
|
+
"number",
|
|
17462
|
+
typeof value
|
|
17463
|
+
);
|
|
17464
|
+
}
|
|
17465
|
+
}
|
|
17466
|
+
}
|
|
17467
|
+
function normalizeOptionalNumber(value) {
|
|
17468
|
+
if (value === void 0 || value === null) {
|
|
17469
|
+
return void 0;
|
|
17470
|
+
}
|
|
17471
|
+
return Number(value);
|
|
17472
|
+
}
|
|
17473
|
+
function validateBoolean(value, fieldName, stepType, required2 = false) {
|
|
17474
|
+
if (required2) {
|
|
17475
|
+
validateRequired(value, fieldName, stepType);
|
|
17476
|
+
}
|
|
17477
|
+
if (value !== void 0 && value !== null && typeof value !== "boolean") {
|
|
17478
|
+
throw new NormalizationError(
|
|
17479
|
+
`Field '${fieldName}' must be a boolean for ${stepType} step`,
|
|
17480
|
+
stepType,
|
|
17481
|
+
fieldName,
|
|
17482
|
+
"boolean",
|
|
17483
|
+
typeof value
|
|
17484
|
+
);
|
|
17485
|
+
}
|
|
17486
|
+
}
|
|
17487
|
+
function validateEnum(value, allowedValues, fieldName, stepType, required2 = false) {
|
|
17488
|
+
if (required2) {
|
|
17489
|
+
validateRequired(value, fieldName, stepType);
|
|
17490
|
+
}
|
|
17491
|
+
if (value !== void 0 && value !== null && !allowedValues.includes(value)) {
|
|
17492
|
+
throw new NormalizationError(
|
|
17493
|
+
`Field '${fieldName}' must be one of [${allowedValues.join(", ")}] for ${stepType} step, got: ${value}`,
|
|
17494
|
+
stepType,
|
|
17495
|
+
fieldName,
|
|
17496
|
+
`one of [${allowedValues.join(", ")}]`,
|
|
17497
|
+
value
|
|
17498
|
+
);
|
|
17499
|
+
}
|
|
17500
|
+
}
|
|
17501
|
+
function validateObject(value, fieldName, stepType, required2 = false) {
|
|
17502
|
+
if (required2) {
|
|
17503
|
+
validateRequired(value, fieldName, stepType);
|
|
17504
|
+
}
|
|
17505
|
+
if (value !== void 0 && value !== null) {
|
|
17506
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
17507
|
+
throw new NormalizationError(
|
|
17508
|
+
`Field '${fieldName}' must be an object for ${stepType} step`,
|
|
17509
|
+
stepType,
|
|
17510
|
+
fieldName,
|
|
17511
|
+
"object",
|
|
17512
|
+
Array.isArray(value) ? "array" : typeof value
|
|
17513
|
+
);
|
|
17514
|
+
}
|
|
17515
|
+
}
|
|
17516
|
+
}
|
|
17517
|
+
function validateArray(value, fieldName, stepType, required2 = false) {
|
|
17518
|
+
if (required2) {
|
|
17519
|
+
validateRequired(value, fieldName, stepType);
|
|
17520
|
+
}
|
|
17521
|
+
if (value !== void 0 && value !== null && !Array.isArray(value)) {
|
|
17522
|
+
throw new NormalizationError(
|
|
17523
|
+
`Field '${fieldName}' must be an array for ${stepType} step`,
|
|
17524
|
+
stepType,
|
|
17525
|
+
fieldName,
|
|
17526
|
+
"array",
|
|
17527
|
+
typeof value
|
|
17528
|
+
);
|
|
17529
|
+
}
|
|
17530
|
+
}
|
|
17531
|
+
function validateConfig(config3, stepType) {
|
|
17532
|
+
if (!config3 || typeof config3 !== "object" || Array.isArray(config3)) {
|
|
17533
|
+
throw new NormalizationError(
|
|
17534
|
+
`Config must be a valid object for ${stepType} step`,
|
|
17535
|
+
stepType,
|
|
17536
|
+
"config",
|
|
17537
|
+
"object",
|
|
17538
|
+
typeof config3
|
|
17539
|
+
);
|
|
17540
|
+
}
|
|
17541
|
+
}
|
|
17542
|
+
function normalizeErrorHandling(value) {
|
|
17543
|
+
if (!value) return void 0;
|
|
17544
|
+
if (typeof value === "object" && value !== null) {
|
|
17545
|
+
const objectValue = value;
|
|
17546
|
+
const onError = objectValue.onError || objectValue.on_error || "continue";
|
|
17547
|
+
return {
|
|
17548
|
+
onError: onError === "default" ? "continue" : onError,
|
|
17549
|
+
fallbacks: objectValue.fallbacks
|
|
17550
|
+
};
|
|
17551
|
+
}
|
|
17552
|
+
if (typeof value === "string") {
|
|
17553
|
+
const validModes = ["fail", "continue", "fallback", "default"];
|
|
17554
|
+
if (!validModes.includes(value)) {
|
|
17555
|
+
return { onError: "continue" };
|
|
17556
|
+
}
|
|
17557
|
+
return {
|
|
17558
|
+
onError: value === "default" ? "continue" : value
|
|
17559
|
+
};
|
|
17560
|
+
}
|
|
17561
|
+
return void 0;
|
|
17562
|
+
}
|
|
17563
|
+
function validateAndNormalizeErrorHandling(value, fieldName, stepType) {
|
|
17564
|
+
if (value === void 0 || value === null) return void 0;
|
|
17565
|
+
if (typeof value === "string") {
|
|
17566
|
+
const validModes = ["fail", "continue", "fallback", "default"];
|
|
17567
|
+
if (!validModes.includes(value)) {
|
|
17568
|
+
throw new NormalizationError(
|
|
17569
|
+
`Field '${fieldName}' must be one of [${validModes.join(", ")}] or an error handling object for ${stepType} step, got: ${value}`,
|
|
17570
|
+
stepType,
|
|
17571
|
+
fieldName,
|
|
17572
|
+
`one of [${validModes.join(", ")}] or object`,
|
|
17573
|
+
value
|
|
17574
|
+
);
|
|
17575
|
+
}
|
|
17576
|
+
}
|
|
17577
|
+
if (typeof value === "object" && value !== null) {
|
|
17578
|
+
const objectValue = value;
|
|
17579
|
+
const onError = objectValue.onError || objectValue.on_error;
|
|
17580
|
+
if (onError) {
|
|
17581
|
+
const validModes = ["fail", "continue", "fallback", "default"];
|
|
17582
|
+
if (!validModes.includes(onError)) {
|
|
17583
|
+
throw new NormalizationError(
|
|
17584
|
+
`Field '${fieldName}.onError' must be one of [${validModes.join(", ")}] for ${stepType} step, got: ${onError}`,
|
|
17585
|
+
stepType,
|
|
17586
|
+
`${fieldName}.onError`,
|
|
17587
|
+
`one of [${validModes.join(", ")}]`,
|
|
17588
|
+
onError
|
|
17589
|
+
);
|
|
17590
|
+
}
|
|
17591
|
+
}
|
|
17592
|
+
}
|
|
17593
|
+
return normalizeErrorHandling(value);
|
|
17594
|
+
}
|
|
17595
|
+
function normalizeContextStep(apiStep, options = {}) {
|
|
17596
|
+
if (!apiStep || typeof apiStep !== "object") {
|
|
17597
|
+
throw new NormalizationError(
|
|
17598
|
+
"Step must be a valid object",
|
|
17599
|
+
"unknown",
|
|
17600
|
+
"apiStep",
|
|
17601
|
+
"object",
|
|
17602
|
+
typeof apiStep
|
|
17603
|
+
);
|
|
17604
|
+
}
|
|
17605
|
+
validateRequired(apiStep.id, "id", apiStep.type || "unknown");
|
|
17606
|
+
validateRequired(apiStep.type, "type", "step");
|
|
17607
|
+
validateRequired(apiStep.name, "name", apiStep.type || "unknown");
|
|
17608
|
+
validateRequired(apiStep.order, "order", apiStep.type || "unknown");
|
|
17609
|
+
validateString(apiStep.id, "id", apiStep.type, true);
|
|
17610
|
+
validateString(apiStep.type, "type", "step", true);
|
|
17611
|
+
validateString(apiStep.name, "name", apiStep.type, true);
|
|
17612
|
+
validateNumber(apiStep.order, "order", apiStep.type, true);
|
|
17613
|
+
const validStepTypes = [
|
|
17614
|
+
"crawl",
|
|
17615
|
+
"fetch-url",
|
|
17616
|
+
"retrieve-record",
|
|
17617
|
+
"fetch-github",
|
|
17618
|
+
"api-call",
|
|
17619
|
+
"transform-data",
|
|
17620
|
+
"template",
|
|
17621
|
+
"conditional",
|
|
17622
|
+
"set-variable",
|
|
17623
|
+
"upsert-record",
|
|
17624
|
+
"send-email",
|
|
17625
|
+
"send-text",
|
|
17626
|
+
"send-event",
|
|
17627
|
+
"send-stream",
|
|
17628
|
+
"update-record",
|
|
17629
|
+
"search",
|
|
17630
|
+
"generate-embedding",
|
|
17631
|
+
"vector-search",
|
|
17632
|
+
"tool-call",
|
|
17633
|
+
"wait-until",
|
|
17634
|
+
"paginate-api",
|
|
17635
|
+
"store-vector",
|
|
17636
|
+
"execute-agent",
|
|
17637
|
+
"store-asset",
|
|
17638
|
+
"generate-pdf",
|
|
17639
|
+
"save-memory",
|
|
17640
|
+
"recall-memory",
|
|
17641
|
+
"memory-summary"
|
|
17642
|
+
];
|
|
17643
|
+
if (!validStepTypes.includes(apiStep.type)) {
|
|
17644
|
+
throw new NormalizationError(
|
|
17645
|
+
`Unknown context step type: ${apiStep.type}. Must be one of: ${validStepTypes.join(", ")}`,
|
|
17646
|
+
apiStep.type,
|
|
17647
|
+
"type",
|
|
17648
|
+
`one of [${validStepTypes.join(", ")}]`,
|
|
17649
|
+
apiStep.type
|
|
17650
|
+
);
|
|
17651
|
+
}
|
|
17652
|
+
const baseStep = {
|
|
17653
|
+
id: apiStep.id,
|
|
17654
|
+
type: apiStep.type,
|
|
17655
|
+
name: apiStep.name,
|
|
17656
|
+
order: apiStep.order,
|
|
17657
|
+
enabled: apiStep.enabled ?? true
|
|
17658
|
+
};
|
|
17659
|
+
try {
|
|
17660
|
+
switch (apiStep.type) {
|
|
17661
|
+
case "crawl":
|
|
17662
|
+
return {
|
|
17663
|
+
...baseStep,
|
|
17664
|
+
type: "crawl",
|
|
17665
|
+
config: normalizeCrawlConfig(apiStep.config)
|
|
17666
|
+
};
|
|
17667
|
+
case "fetch-url":
|
|
17668
|
+
return {
|
|
17669
|
+
...baseStep,
|
|
17670
|
+
type: "fetch-url",
|
|
17671
|
+
config: normalizeFetchUrlConfig(apiStep.config)
|
|
17672
|
+
};
|
|
17673
|
+
case "retrieve-record":
|
|
17674
|
+
return {
|
|
17675
|
+
...baseStep,
|
|
17676
|
+
type: "retrieve-record",
|
|
17677
|
+
config: normalizeRetrieveRecordConfig(apiStep.config)
|
|
17678
|
+
};
|
|
17679
|
+
case "fetch-github":
|
|
17680
|
+
return {
|
|
17681
|
+
...baseStep,
|
|
17682
|
+
type: "fetch-github",
|
|
17683
|
+
config: normalizeFetchGithubConfig(apiStep.config)
|
|
17684
|
+
};
|
|
17685
|
+
case "api-call":
|
|
17686
|
+
return {
|
|
17687
|
+
...baseStep,
|
|
17688
|
+
type: "api-call",
|
|
17689
|
+
config: normalizeApiCallConfig(apiStep.config)
|
|
17690
|
+
};
|
|
17691
|
+
case "transform-data":
|
|
17692
|
+
return {
|
|
17693
|
+
...baseStep,
|
|
17694
|
+
type: "transform-data",
|
|
17695
|
+
config: normalizeTransformDataConfig(apiStep.config)
|
|
17696
|
+
};
|
|
17697
|
+
case "template":
|
|
17698
|
+
return {
|
|
17699
|
+
...baseStep,
|
|
17700
|
+
type: "template",
|
|
17701
|
+
config: normalizeTemplateConfig(apiStep.config)
|
|
17702
|
+
};
|
|
17703
|
+
case "conditional":
|
|
17704
|
+
return {
|
|
17705
|
+
...baseStep,
|
|
17706
|
+
type: "conditional",
|
|
17707
|
+
config: normalizeConditionalConfig(apiStep.config)
|
|
17708
|
+
};
|
|
17709
|
+
case "set-variable":
|
|
17710
|
+
return {
|
|
17711
|
+
...baseStep,
|
|
17712
|
+
type: "set-variable",
|
|
17713
|
+
config: normalizeSetVariableConfig(apiStep.config)
|
|
17714
|
+
};
|
|
17715
|
+
case "upsert-record":
|
|
17716
|
+
return {
|
|
17717
|
+
...baseStep,
|
|
17718
|
+
type: "upsert-record",
|
|
17719
|
+
config: normalizeUpsertRecordConfig(apiStep.config)
|
|
17720
|
+
};
|
|
17721
|
+
case "send-email":
|
|
17722
|
+
return {
|
|
17723
|
+
...baseStep,
|
|
17724
|
+
type: "send-email",
|
|
17725
|
+
config: normalizeSendEmailConfig(apiStep.config, options)
|
|
17726
|
+
};
|
|
17727
|
+
case "send-text":
|
|
17728
|
+
return {
|
|
17729
|
+
...baseStep,
|
|
17730
|
+
type: "send-text",
|
|
17731
|
+
config: normalizeSendTextConfig(apiStep.config)
|
|
17732
|
+
};
|
|
17733
|
+
case "send-event":
|
|
17734
|
+
return {
|
|
17735
|
+
...baseStep,
|
|
17736
|
+
type: "send-event",
|
|
17737
|
+
config: normalizeSendEventConfig(apiStep.config)
|
|
17738
|
+
};
|
|
17739
|
+
case "send-stream":
|
|
17740
|
+
return {
|
|
17741
|
+
...baseStep,
|
|
17742
|
+
type: "send-stream",
|
|
17743
|
+
config: normalizeSendStreamConfig(apiStep.config)
|
|
17744
|
+
};
|
|
17745
|
+
case "update-record":
|
|
17746
|
+
return {
|
|
17747
|
+
...baseStep,
|
|
17748
|
+
type: "update-record",
|
|
17749
|
+
config: normalizeUpdateRecordConfig(apiStep.config)
|
|
17750
|
+
};
|
|
17751
|
+
case "search":
|
|
17752
|
+
return {
|
|
17753
|
+
...baseStep,
|
|
17754
|
+
type: "search",
|
|
17755
|
+
config: normalizeSearchConfig(apiStep.config)
|
|
17756
|
+
};
|
|
17757
|
+
case "generate-embedding":
|
|
17758
|
+
return {
|
|
17759
|
+
...baseStep,
|
|
17760
|
+
type: "generate-embedding",
|
|
17761
|
+
config: normalizeGenerateEmbeddingConfig(apiStep.config)
|
|
17762
|
+
};
|
|
17763
|
+
case "vector-search":
|
|
17764
|
+
return {
|
|
17765
|
+
...baseStep,
|
|
17766
|
+
type: "vector-search",
|
|
17767
|
+
config: normalizeVectorSearchConfig(apiStep.config)
|
|
17768
|
+
};
|
|
17769
|
+
case "paginate-api":
|
|
17770
|
+
return {
|
|
17771
|
+
...baseStep,
|
|
17772
|
+
type: "paginate-api",
|
|
17773
|
+
config: normalizePaginateApiConfig(apiStep.config)
|
|
17774
|
+
};
|
|
17775
|
+
case "store-vector":
|
|
17776
|
+
return {
|
|
17777
|
+
...baseStep,
|
|
17778
|
+
type: "store-vector",
|
|
17779
|
+
config: normalizeStoreVectorConfig(apiStep.config)
|
|
17780
|
+
};
|
|
17781
|
+
case "tool-call":
|
|
17782
|
+
return {
|
|
17783
|
+
...baseStep,
|
|
17784
|
+
type: "tool-call",
|
|
17785
|
+
config: normalizeToolCallConfig(apiStep.config)
|
|
17786
|
+
};
|
|
17787
|
+
case "wait-until":
|
|
17788
|
+
return {
|
|
17789
|
+
...baseStep,
|
|
17790
|
+
type: "wait-until",
|
|
17791
|
+
config: normalizeWaitUntilConfig(apiStep.config)
|
|
17792
|
+
};
|
|
17793
|
+
case "execute-agent":
|
|
17794
|
+
return {
|
|
17795
|
+
...baseStep,
|
|
17796
|
+
type: "execute-agent",
|
|
17797
|
+
config: normalizeExecuteAgentConfig(apiStep.config)
|
|
17798
|
+
};
|
|
17799
|
+
case "store-asset":
|
|
17800
|
+
return {
|
|
17801
|
+
...baseStep,
|
|
17802
|
+
type: "store-asset",
|
|
17803
|
+
config: normalizeStoreAssetConfig(apiStep.config)
|
|
17804
|
+
};
|
|
17805
|
+
case "generate-pdf":
|
|
17806
|
+
return {
|
|
17807
|
+
...baseStep,
|
|
17808
|
+
type: "generate-pdf",
|
|
17809
|
+
config: normalizeGeneratePdfConfig(apiStep.config)
|
|
17810
|
+
};
|
|
17811
|
+
case "save-memory":
|
|
17812
|
+
return {
|
|
17813
|
+
...baseStep,
|
|
17814
|
+
type: "save-memory",
|
|
17815
|
+
config: normalizeSaveMemoryConfig(apiStep.config)
|
|
17816
|
+
};
|
|
17817
|
+
case "recall-memory":
|
|
17818
|
+
return {
|
|
17819
|
+
...baseStep,
|
|
17820
|
+
type: "recall-memory",
|
|
17821
|
+
config: normalizeRecallMemoryConfig(apiStep.config)
|
|
17822
|
+
};
|
|
17823
|
+
case "memory-summary":
|
|
17824
|
+
return {
|
|
17825
|
+
...baseStep,
|
|
17826
|
+
type: "memory-summary",
|
|
17827
|
+
config: normalizeMemorySummaryConfig(apiStep.config)
|
|
17828
|
+
};
|
|
17829
|
+
default:
|
|
17830
|
+
throw new NormalizationError(
|
|
17831
|
+
`Unknown context step type: ${apiStep.type}`,
|
|
17832
|
+
apiStep.type,
|
|
17833
|
+
"type",
|
|
17834
|
+
"valid step type",
|
|
17835
|
+
apiStep.type
|
|
17836
|
+
);
|
|
17837
|
+
}
|
|
17838
|
+
} catch (error51) {
|
|
17839
|
+
if (error51 instanceof NormalizationError) {
|
|
17840
|
+
throw error51;
|
|
17841
|
+
}
|
|
17842
|
+
throw new NormalizationError(
|
|
17843
|
+
`Failed to normalize ${apiStep.type} step: ${error51 instanceof Error ? error51.message : String(error51)}`,
|
|
17844
|
+
apiStep.type,
|
|
17845
|
+
void 0,
|
|
17846
|
+
void 0,
|
|
17847
|
+
error51
|
|
17848
|
+
);
|
|
17849
|
+
}
|
|
17850
|
+
}
|
|
17851
|
+
function normalizeHttpConfig(config3) {
|
|
17852
|
+
validateObject(config3, "http", "http-config", true);
|
|
17853
|
+
validateString(config3.url, "http.url", "http-config", true);
|
|
17854
|
+
if (config3.method) {
|
|
17855
|
+
validateEnum(
|
|
17856
|
+
config3.method,
|
|
17857
|
+
["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
17858
|
+
"http.method",
|
|
17859
|
+
"http-config"
|
|
17860
|
+
);
|
|
17861
|
+
}
|
|
17862
|
+
if (config3.headers !== void 0 && config3.headers !== null) {
|
|
17863
|
+
validateObject(config3.headers, "http.headers", "http-config");
|
|
17864
|
+
}
|
|
17865
|
+
if (config3.timeout !== void 0 && config3.timeout !== null) {
|
|
17866
|
+
validateNumber(config3.timeout, "http.timeout", "http-config");
|
|
17867
|
+
}
|
|
17868
|
+
return {
|
|
17869
|
+
url: config3.url,
|
|
17870
|
+
method: config3.method,
|
|
17871
|
+
headers: config3.headers,
|
|
17872
|
+
// Preserve user headers as-is
|
|
17873
|
+
body: config3.body,
|
|
17874
|
+
timeout: config3.timeout
|
|
17875
|
+
};
|
|
17876
|
+
}
|
|
17877
|
+
function normalizeCrawlConfig(config3) {
|
|
17878
|
+
validateConfig(config3, "crawl");
|
|
17879
|
+
const url2 = config3.url;
|
|
17880
|
+
validateString(url2, "url", "crawl", true);
|
|
17881
|
+
validateString(config3.outputVariable ?? config3.output_variable, "outputVariable", "crawl", true);
|
|
17882
|
+
const limitRaw = config3.limit;
|
|
17883
|
+
const depthRaw = config3.depth;
|
|
17884
|
+
const maxAgeRaw = config3.maxAge ?? config3.max_age;
|
|
17885
|
+
const modifiedSince = config3.modifiedSince ?? config3.modified_since;
|
|
17886
|
+
const setExtraHTTPHeaders = config3.setExtraHTTPHeaders ?? config3.set_extra_http_headers;
|
|
17887
|
+
const gotoOptions = config3.gotoOptions ?? config3.goto_options;
|
|
17888
|
+
const waitForSelector = config3.waitForSelector ?? config3.wait_for_selector;
|
|
17889
|
+
const rejectResourceTypes = config3.rejectResourceTypes ?? config3.reject_resource_types;
|
|
17890
|
+
const rejectRequestPattern = config3.rejectRequestPattern ?? config3.reject_request_pattern;
|
|
17891
|
+
const userAgent = config3.userAgent ?? config3.user_agent;
|
|
17892
|
+
const jsonOptions = config3.jsonOptions ?? config3.json_options;
|
|
17893
|
+
const pollIntervalMsRaw = config3.pollIntervalMs ?? config3.poll_interval_ms;
|
|
17894
|
+
const completionTimeoutMsRaw = config3.completionTimeoutMs ?? config3.completion_timeout_ms;
|
|
17895
|
+
if (limitRaw !== void 0 && limitRaw !== null) validateNumber(limitRaw, "limit", "crawl");
|
|
17896
|
+
if (depthRaw !== void 0 && depthRaw !== null) validateNumber(depthRaw, "depth", "crawl");
|
|
17897
|
+
if (config3.source !== void 0) validateString(config3.source, "source", "crawl");
|
|
17898
|
+
if (config3.formats !== void 0) validateArray(config3.formats, "formats", "crawl");
|
|
17899
|
+
if (config3.render !== void 0) validateBoolean(config3.render, "render", "crawl");
|
|
17900
|
+
if (maxAgeRaw !== void 0 && maxAgeRaw !== null) validateNumber(maxAgeRaw, "maxAge", "crawl");
|
|
17901
|
+
if (modifiedSince !== void 0) validateString(modifiedSince, "modifiedSince", "crawl");
|
|
17902
|
+
if (config3.options !== void 0) validateObject(config3.options, "options", "crawl");
|
|
17903
|
+
if (config3.authenticate !== void 0) validateObject(config3.authenticate, "authenticate", "crawl");
|
|
17904
|
+
if (config3.cookies !== void 0) validateArray(config3.cookies, "cookies", "crawl");
|
|
17905
|
+
if (setExtraHTTPHeaders !== void 0) {
|
|
17906
|
+
validateObject(setExtraHTTPHeaders, "setExtraHTTPHeaders", "crawl");
|
|
17907
|
+
}
|
|
17908
|
+
if (gotoOptions !== void 0) validateObject(gotoOptions, "gotoOptions", "crawl");
|
|
17909
|
+
if (waitForSelector !== void 0) validateString(waitForSelector, "waitForSelector", "crawl");
|
|
17910
|
+
if (rejectResourceTypes !== void 0) {
|
|
17911
|
+
validateArray(rejectResourceTypes, "rejectResourceTypes", "crawl");
|
|
17912
|
+
}
|
|
17913
|
+
if (rejectRequestPattern !== void 0) {
|
|
17914
|
+
if (typeof rejectRequestPattern !== "string" && !Array.isArray(rejectRequestPattern)) {
|
|
17915
|
+
throw new NormalizationError(
|
|
17916
|
+
"Field 'rejectRequestPattern' must be a string or array for crawl step",
|
|
17917
|
+
"crawl",
|
|
17918
|
+
"rejectRequestPattern",
|
|
17919
|
+
"string | array",
|
|
17920
|
+
typeof rejectRequestPattern
|
|
17921
|
+
);
|
|
17922
|
+
}
|
|
17923
|
+
}
|
|
17924
|
+
if (userAgent !== void 0) validateString(userAgent, "userAgent", "crawl");
|
|
17925
|
+
if (jsonOptions !== void 0) validateObject(jsonOptions, "jsonOptions", "crawl");
|
|
17926
|
+
if (config3.streamOutput !== void 0) validateBoolean(config3.streamOutput, "streamOutput", "crawl");
|
|
17927
|
+
if (pollIntervalMsRaw !== void 0 && pollIntervalMsRaw !== null) {
|
|
17928
|
+
validateNumber(pollIntervalMsRaw, "pollIntervalMs", "crawl");
|
|
17929
|
+
}
|
|
17930
|
+
if (completionTimeoutMsRaw !== void 0 && completionTimeoutMsRaw !== null) {
|
|
17931
|
+
validateNumber(completionTimeoutMsRaw, "completionTimeoutMs", "crawl");
|
|
17932
|
+
}
|
|
17933
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
17934
|
+
config3.errorHandling ?? config3.error_handling,
|
|
17935
|
+
"errorHandling",
|
|
17936
|
+
"crawl"
|
|
17937
|
+
);
|
|
17938
|
+
const limit = normalizeOptionalNumber(limitRaw);
|
|
17939
|
+
const depth = normalizeOptionalNumber(depthRaw);
|
|
17940
|
+
const maxAge = normalizeOptionalNumber(maxAgeRaw);
|
|
17941
|
+
const pollIntervalMs = normalizeOptionalNumber(pollIntervalMsRaw);
|
|
17942
|
+
const completionTimeoutMs = normalizeOptionalNumber(completionTimeoutMsRaw);
|
|
17943
|
+
return {
|
|
17944
|
+
url: url2,
|
|
17945
|
+
limit,
|
|
17946
|
+
depth,
|
|
17947
|
+
source: config3.source,
|
|
17948
|
+
formats: config3.formats,
|
|
17949
|
+
render: config3.render,
|
|
17950
|
+
maxAge,
|
|
17951
|
+
modifiedSince,
|
|
17952
|
+
options: config3.options,
|
|
17953
|
+
authenticate: config3.authenticate,
|
|
17954
|
+
cookies: config3.cookies,
|
|
17955
|
+
setExtraHTTPHeaders,
|
|
17956
|
+
gotoOptions,
|
|
17957
|
+
waitForSelector,
|
|
17958
|
+
rejectResourceTypes,
|
|
17959
|
+
rejectRequestPattern,
|
|
17960
|
+
userAgent,
|
|
17961
|
+
jsonOptions,
|
|
17962
|
+
outputVariable: config3.outputVariable ?? config3.output_variable,
|
|
17963
|
+
streamOutput: config3.streamOutput ?? config3.stream_output,
|
|
17964
|
+
errorHandling,
|
|
17965
|
+
defaultValue: config3.defaultValue ?? config3.default_value,
|
|
17966
|
+
pollIntervalMs,
|
|
17967
|
+
completionTimeoutMs,
|
|
17968
|
+
asyncCrawl: config3.asyncCrawl
|
|
17969
|
+
};
|
|
17970
|
+
}
|
|
17971
|
+
function normalizeAuthConfig(config3) {
|
|
17972
|
+
if (!config3) return void 0;
|
|
17973
|
+
validateObject(config3, "auth", "auth-config", true);
|
|
17974
|
+
validateEnum(
|
|
17975
|
+
config3.type,
|
|
17976
|
+
["none", "bearer", "basic", "api-key", "custom"],
|
|
17977
|
+
"auth.type",
|
|
17978
|
+
"auth-config",
|
|
17979
|
+
true
|
|
17980
|
+
);
|
|
17981
|
+
if (config3.token) validateString(config3.token, "auth.token", "auth-config");
|
|
17982
|
+
if (config3.username) validateString(config3.username, "auth.username", "auth-config");
|
|
17983
|
+
if (config3.password) validateString(config3.password, "auth.password", "auth-config");
|
|
17984
|
+
if (config3.apiKey) validateString(config3.apiKey, "auth.apiKey", "auth-config");
|
|
17985
|
+
if (config3.headerName) validateString(config3.headerName, "auth.headerName", "auth-config");
|
|
17986
|
+
if (config3.customHeaders !== void 0 && config3.customHeaders !== null) {
|
|
17987
|
+
validateObject(config3.customHeaders, "auth.customHeaders", "auth-config");
|
|
17988
|
+
}
|
|
17989
|
+
return {
|
|
17990
|
+
type: config3.type,
|
|
17991
|
+
token: config3.token,
|
|
17992
|
+
username: config3.username,
|
|
17993
|
+
password: config3.password,
|
|
17994
|
+
apiKey: config3.apiKey,
|
|
17995
|
+
headerName: config3.headerName,
|
|
17996
|
+
customHeaders: config3.customHeaders
|
|
17997
|
+
};
|
|
17998
|
+
}
|
|
17999
|
+
function normalizeFirecrawlConfig(config3) {
|
|
18000
|
+
if (!config3) return void 0;
|
|
18001
|
+
return {
|
|
18002
|
+
formats: config3.formats,
|
|
18003
|
+
actions: config3.actions,
|
|
18004
|
+
location: config3.location,
|
|
18005
|
+
maxAge: config3.maxAge,
|
|
18006
|
+
storeInCache: config3.storeInCache,
|
|
18007
|
+
onlyMainContent: config3.onlyMainContent,
|
|
18008
|
+
jsonSchema: config3.jsonSchema,
|
|
18009
|
+
jsonPrompt: config3.jsonPrompt
|
|
18010
|
+
};
|
|
18011
|
+
}
|
|
18012
|
+
function normalizeFetchUrlConfig(config3) {
|
|
18013
|
+
validateConfig(config3, "fetch-url");
|
|
18014
|
+
validateObject(config3.http, "http", "fetch-url", true);
|
|
18015
|
+
validateString(config3.outputVariable, "outputVariable", "fetch-url", true);
|
|
18016
|
+
if (config3.responseType) {
|
|
18017
|
+
validateEnum(config3.responseType, ["json", "text", "xml"], "responseType", "fetch-url");
|
|
18018
|
+
}
|
|
18019
|
+
if (config3.markdownIfAvailable !== void 0) {
|
|
18020
|
+
validateBoolean(config3.markdownIfAvailable, "markdownIfAvailable", "fetch-url");
|
|
18021
|
+
}
|
|
18022
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18023
|
+
config3.errorHandling,
|
|
18024
|
+
"errorHandling",
|
|
18025
|
+
"fetch-url"
|
|
18026
|
+
);
|
|
18027
|
+
if (config3.fetchMethod) {
|
|
18028
|
+
validateEnum(config3.fetchMethod, ["standard", "firecrawl"], "fetchMethod", "fetch-url");
|
|
18029
|
+
}
|
|
18030
|
+
return {
|
|
18031
|
+
http: normalizeHttpConfig(config3.http),
|
|
18032
|
+
auth: normalizeAuthConfig(config3.auth),
|
|
18033
|
+
responseType: config3.responseType,
|
|
18034
|
+
markdownIfAvailable: config3.markdownIfAvailable,
|
|
18035
|
+
outputVariable: config3.outputVariable,
|
|
18036
|
+
streamOutput: config3.streamOutput,
|
|
18037
|
+
errorHandling,
|
|
18038
|
+
defaultValue: config3.defaultValue,
|
|
18039
|
+
fetchMethod: config3.fetchMethod,
|
|
18040
|
+
firecrawl: normalizeFirecrawlConfig(config3.firecrawl)
|
|
18041
|
+
};
|
|
18042
|
+
}
|
|
18043
|
+
function normalizeRetrieveRecordConfig(config3) {
|
|
18044
|
+
validateConfig(config3, "retrieve-record");
|
|
18045
|
+
const filter = config3.recordFilter;
|
|
18046
|
+
const hasFilter = filter && typeof filter === "object" && typeof filter.type === "string" && filter.type.length > 0;
|
|
18047
|
+
if (!config3.recordId && !config3.recordType && !config3.recordName && !hasFilter) {
|
|
18048
|
+
throw new NormalizationError(
|
|
18049
|
+
`retrieve-record step requires at least one of 'recordId', 'recordType', 'recordName', or 'recordFilter'`,
|
|
18050
|
+
"retrieve-record",
|
|
18051
|
+
"recordId/recordType/recordName/recordFilter",
|
|
18052
|
+
"at least one identification field",
|
|
18053
|
+
void 0
|
|
18054
|
+
);
|
|
18055
|
+
}
|
|
18056
|
+
validateString(config3.outputVariable, "outputVariable", "retrieve-record", true);
|
|
18057
|
+
if (config3.fieldsToInclude)
|
|
18058
|
+
validateString(config3.fieldsToInclude, "fieldsToInclude", "retrieve-record");
|
|
18059
|
+
if (config3.fieldsToExclude)
|
|
18060
|
+
validateString(config3.fieldsToExclude, "fieldsToExclude", "retrieve-record");
|
|
18061
|
+
if (config3.availableFields)
|
|
18062
|
+
validateArray(config3.availableFields, "availableFields", "retrieve-record");
|
|
18063
|
+
return {
|
|
18064
|
+
retrievalMode: config3.retrievalMode,
|
|
18065
|
+
recordType: config3.recordType,
|
|
18066
|
+
recordName: config3.recordName,
|
|
18067
|
+
recordId: config3.recordId,
|
|
18068
|
+
recordFilter: config3.recordFilter,
|
|
18069
|
+
fieldsToInclude: config3.fieldsToInclude,
|
|
18070
|
+
fieldsToExclude: config3.fieldsToExclude,
|
|
18071
|
+
availableFields: config3.availableFields,
|
|
18072
|
+
outputVariable: config3.outputVariable
|
|
18073
|
+
};
|
|
18074
|
+
}
|
|
18075
|
+
function normalizeFetchGithubConfig(config3) {
|
|
18076
|
+
validateConfig(config3, "fetch-github");
|
|
18077
|
+
validateString(config3.repository, "repository", "fetch-github", true);
|
|
18078
|
+
validateString(config3.outputVariable, "outputVariable", "fetch-github", true);
|
|
18079
|
+
if (config3.path) validateString(config3.path, "path", "fetch-github");
|
|
18080
|
+
if (config3.branch) validateString(config3.branch, "branch", "fetch-github");
|
|
18081
|
+
if (config3.token) validateString(config3.token, "token", "fetch-github");
|
|
18082
|
+
if (config3.contentType) {
|
|
18083
|
+
validateEnum(config3.contentType, ["raw", "metadata", "both"], "contentType", "fetch-github");
|
|
18084
|
+
}
|
|
18085
|
+
if (config3.includePatterns)
|
|
18086
|
+
validateArray(config3.includePatterns, "includePatterns", "fetch-github");
|
|
18087
|
+
if (config3.excludePatterns)
|
|
18088
|
+
validateArray(config3.excludePatterns, "excludePatterns", "fetch-github");
|
|
18089
|
+
if (config3.compress !== void 0 && config3.compress !== null) {
|
|
18090
|
+
validateBoolean(config3.compress, "compress", "fetch-github");
|
|
18091
|
+
}
|
|
18092
|
+
if (config3.style) {
|
|
18093
|
+
validateEnum(config3.style, ["xml", "json", "markdown"], "style", "fetch-github");
|
|
18094
|
+
}
|
|
18095
|
+
return {
|
|
18096
|
+
repository: config3.repository,
|
|
18097
|
+
path: config3.path,
|
|
18098
|
+
branch: config3.branch,
|
|
18099
|
+
token: config3.token,
|
|
18100
|
+
outputVariable: config3.outputVariable,
|
|
18101
|
+
contentType: config3.contentType,
|
|
18102
|
+
includePatterns: config3.includePatterns,
|
|
18103
|
+
excludePatterns: config3.excludePatterns,
|
|
18104
|
+
compress: config3.compress,
|
|
18105
|
+
style: config3.style
|
|
18106
|
+
};
|
|
18107
|
+
}
|
|
18108
|
+
function normalizeApiCallConfig(config3) {
|
|
18109
|
+
validateConfig(config3, "api-call");
|
|
18110
|
+
validateObject(config3.http, "http", "api-call", true);
|
|
18111
|
+
validateString(config3.outputVariable, "outputVariable", "api-call", true);
|
|
18112
|
+
if (config3.requestTemplate !== void 0 && config3.requestTemplate !== null) {
|
|
18113
|
+
validateString(config3.requestTemplate, "requestTemplate", "api-call");
|
|
18114
|
+
}
|
|
18115
|
+
if (config3.responseMapping !== void 0 && config3.responseMapping !== null) {
|
|
18116
|
+
validateObject(config3.responseMapping, "responseMapping", "api-call");
|
|
18117
|
+
}
|
|
18118
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18119
|
+
config3.errorHandling,
|
|
18120
|
+
"errorHandling",
|
|
18121
|
+
"api-call"
|
|
18122
|
+
);
|
|
18123
|
+
return {
|
|
18124
|
+
http: normalizeHttpConfig(config3.http),
|
|
18125
|
+
auth: normalizeAuthConfig(config3.auth),
|
|
18126
|
+
requestTemplate: config3.requestTemplate,
|
|
18127
|
+
responseMapping: config3.responseMapping,
|
|
18128
|
+
// Preserve user mapping keys
|
|
18129
|
+
outputVariable: config3.outputVariable,
|
|
18130
|
+
errorHandling,
|
|
18131
|
+
defaultValue: config3.defaultValue
|
|
18132
|
+
};
|
|
18133
|
+
}
|
|
18134
|
+
function normalizeTransformDataConfig(config3) {
|
|
18135
|
+
validateConfig(config3, "transform-data");
|
|
18136
|
+
validateString(config3.script, "script", "transform-data", true);
|
|
18137
|
+
const outputVariable = config3.outputVariable ?? config3.output_variable;
|
|
18138
|
+
validateString(outputVariable, "outputVariable", "transform-data", true);
|
|
18139
|
+
if (config3.sandboxProvider) {
|
|
18140
|
+
validateEnum(
|
|
18141
|
+
config3.sandboxProvider,
|
|
18142
|
+
["quickjs", "daytona", "cloudflare-worker", "runtype-sandbox", "cloudflare-sandbox"],
|
|
18143
|
+
"sandboxProvider",
|
|
18144
|
+
"transform-data"
|
|
18145
|
+
);
|
|
18146
|
+
if (config3.sandboxProvider === "cloudflare-sandbox") {
|
|
18147
|
+
config3.sandboxProvider = "runtype-sandbox";
|
|
18148
|
+
}
|
|
18149
|
+
}
|
|
18150
|
+
if (config3.language) {
|
|
18151
|
+
validateEnum(
|
|
18152
|
+
config3.language,
|
|
18153
|
+
["javascript", "typescript", "python"],
|
|
18154
|
+
"language",
|
|
18155
|
+
"transform-data"
|
|
18156
|
+
);
|
|
18157
|
+
}
|
|
18158
|
+
if (config3.persistSandbox !== void 0 && typeof config3.persistSandbox !== "boolean") {
|
|
18159
|
+
throw new NormalizationError(
|
|
18160
|
+
"persistSandbox must be a boolean",
|
|
18161
|
+
"transform-data",
|
|
18162
|
+
"persistSandbox",
|
|
18163
|
+
"boolean",
|
|
18164
|
+
config3.persistSandbox
|
|
18165
|
+
);
|
|
18166
|
+
}
|
|
18167
|
+
if (config3.streamOutput !== void 0) {
|
|
18168
|
+
validateBoolean(config3.streamOutput, "streamOutput", "transform-data");
|
|
18169
|
+
}
|
|
18170
|
+
if (config3.reuseSandboxId !== void 0) {
|
|
18171
|
+
validateString(config3.reuseSandboxId, "reuseSandboxId", "transform-data", false);
|
|
18172
|
+
}
|
|
18173
|
+
if (config3.inputMode) {
|
|
18174
|
+
validateEnum(config3.inputMode, ["code", "variable"], "inputMode", "transform-data");
|
|
18175
|
+
}
|
|
18176
|
+
if (config3.packageJson && typeof config3.packageJson !== "string") {
|
|
18177
|
+
throw new NormalizationError("packageJson must be a string", "transform-data");
|
|
18178
|
+
}
|
|
18179
|
+
if (config3.networkAccess !== void 0) {
|
|
18180
|
+
if (config3.networkAccess !== "on" && config3.networkAccess !== "off") {
|
|
18181
|
+
if (typeof config3.networkAccess !== "object" || config3.networkAccess === null || !Array.isArray(config3.networkAccess.allowedHostnames)) {
|
|
18182
|
+
throw new NormalizationError(
|
|
18183
|
+
"networkAccess must be 'on', 'off', or { allowedHostnames: string[] }",
|
|
18184
|
+
"transform-data",
|
|
18185
|
+
"networkAccess"
|
|
18186
|
+
);
|
|
18187
|
+
}
|
|
18188
|
+
if (config3.networkAccess.allowedHostnames.length === 0) {
|
|
18189
|
+
throw new NormalizationError(
|
|
18190
|
+
"allowedHostnames must contain at least one entry",
|
|
18191
|
+
"transform-data",
|
|
18192
|
+
"networkAccess"
|
|
18193
|
+
);
|
|
18194
|
+
}
|
|
18195
|
+
for (const h2 of config3.networkAccess.allowedHostnames) {
|
|
18196
|
+
if (typeof h2 !== "string") {
|
|
18197
|
+
throw new NormalizationError(
|
|
18198
|
+
"allowedHostnames entries must be strings",
|
|
18199
|
+
"transform-data",
|
|
18200
|
+
"networkAccess"
|
|
18201
|
+
);
|
|
18202
|
+
}
|
|
18203
|
+
}
|
|
18204
|
+
}
|
|
18205
|
+
}
|
|
18206
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18207
|
+
config3.errorHandling,
|
|
18208
|
+
"errorHandling",
|
|
18209
|
+
"transform-data"
|
|
18210
|
+
);
|
|
18211
|
+
return {
|
|
18212
|
+
script: config3.script,
|
|
18213
|
+
outputVariable,
|
|
18214
|
+
streamOutput: config3.streamOutput,
|
|
18215
|
+
sandboxProvider: config3.sandboxProvider,
|
|
18216
|
+
language: config3.language,
|
|
18217
|
+
inputMode: config3.inputMode,
|
|
18218
|
+
packageJson: config3.packageJson,
|
|
18219
|
+
persistSandbox: config3.persistSandbox,
|
|
18220
|
+
reuseSandboxId: config3.reuseSandboxId,
|
|
18221
|
+
networkAccess: config3.networkAccess,
|
|
18222
|
+
errorHandling,
|
|
18223
|
+
defaultValue: config3.defaultValue,
|
|
18224
|
+
...config3.tools ? { tools: config3.tools } : {}
|
|
18225
|
+
};
|
|
18226
|
+
}
|
|
18227
|
+
function normalizeTemplateConfig(config3) {
|
|
18228
|
+
validateConfig(config3, "template");
|
|
18229
|
+
validateString(config3.template, "template", "template", true);
|
|
18230
|
+
validateString(config3.outputVariable, "outputVariable", "template", true);
|
|
18231
|
+
validateEnum(
|
|
18232
|
+
config3.outputFormat,
|
|
18233
|
+
["html", "email-html", "markdown", "pdf", "text"],
|
|
18234
|
+
"outputFormat",
|
|
18235
|
+
"template"
|
|
18236
|
+
);
|
|
18237
|
+
if (config3.inputs !== void 0) {
|
|
18238
|
+
if (typeof config3.inputs !== "object" || config3.inputs === null || Array.isArray(config3.inputs)) {
|
|
18239
|
+
throw new NormalizationError("inputs must be an object", "template", "inputs");
|
|
18240
|
+
}
|
|
18241
|
+
for (const [key, value] of Object.entries(config3.inputs)) {
|
|
18242
|
+
if (typeof value !== "string") {
|
|
18243
|
+
throw new NormalizationError(
|
|
18244
|
+
`inputs.${key} must be a string expression`,
|
|
18245
|
+
"template",
|
|
18246
|
+
`inputs.${key}`
|
|
18247
|
+
);
|
|
18248
|
+
}
|
|
18249
|
+
}
|
|
18250
|
+
}
|
|
18251
|
+
if (config3.partials !== void 0) {
|
|
18252
|
+
if (typeof config3.partials !== "object" || config3.partials === null || Array.isArray(config3.partials)) {
|
|
18253
|
+
throw new NormalizationError("partials must be an object", "template", "partials");
|
|
18254
|
+
}
|
|
18255
|
+
for (const [key, value] of Object.entries(config3.partials)) {
|
|
18256
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(key)) {
|
|
18257
|
+
throw new NormalizationError(
|
|
18258
|
+
`partials.${key} key must be a simple identifier`,
|
|
18259
|
+
"template",
|
|
18260
|
+
`partials.${key}`
|
|
18261
|
+
);
|
|
18262
|
+
}
|
|
18263
|
+
if (typeof value !== "string") {
|
|
18264
|
+
throw new NormalizationError(
|
|
18265
|
+
`partials.${key} must be a string template`,
|
|
18266
|
+
"template",
|
|
18267
|
+
`partials.${key}`
|
|
18268
|
+
);
|
|
18269
|
+
}
|
|
18270
|
+
}
|
|
18271
|
+
}
|
|
18272
|
+
if (config3.pdfOptions !== void 0 && config3.outputFormat !== "pdf") {
|
|
18273
|
+
throw new NormalizationError(
|
|
18274
|
+
'pdfOptions is only allowed when outputFormat is "pdf"',
|
|
18275
|
+
"template",
|
|
18276
|
+
"pdfOptions"
|
|
18277
|
+
);
|
|
18278
|
+
}
|
|
18279
|
+
if (config3.asArtifact !== void 0 && typeof config3.asArtifact !== "boolean") {
|
|
18280
|
+
throw new NormalizationError("asArtifact must be a boolean", "template", "asArtifact");
|
|
18281
|
+
}
|
|
18282
|
+
if (config3.sampleData !== void 0) {
|
|
18283
|
+
validateArray(config3.sampleData, "sampleData", "template");
|
|
18284
|
+
for (const [i, scenario] of config3.sampleData.entries()) {
|
|
18285
|
+
if (typeof scenario !== "object" || scenario === null || Array.isArray(scenario)) {
|
|
18286
|
+
throw new NormalizationError(`sampleData[${i}] must be an object`, "template", `sampleData[${i}]`);
|
|
18287
|
+
}
|
|
18288
|
+
validateString(scenario.name, `sampleData[${i}].name`, "template", true);
|
|
18289
|
+
if (typeof scenario.data !== "object" || scenario.data === null || Array.isArray(scenario.data)) {
|
|
18290
|
+
throw new NormalizationError(`sampleData[${i}].data must be an object`, "template", `sampleData[${i}].data`);
|
|
18291
|
+
}
|
|
18292
|
+
}
|
|
18293
|
+
}
|
|
18294
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18295
|
+
config3.errorHandling,
|
|
18296
|
+
"errorHandling",
|
|
18297
|
+
"template"
|
|
18298
|
+
);
|
|
18299
|
+
return {
|
|
18300
|
+
template: config3.template,
|
|
18301
|
+
inputs: config3.inputs,
|
|
18302
|
+
outputFormat: config3.outputFormat,
|
|
18303
|
+
outputVariable: config3.outputVariable,
|
|
18304
|
+
partials: config3.partials,
|
|
18305
|
+
pdfOptions: config3.pdfOptions,
|
|
18306
|
+
asArtifact: config3.asArtifact,
|
|
18307
|
+
streamOutput: config3.streamOutput,
|
|
18308
|
+
errorHandling,
|
|
18309
|
+
defaultValue: config3.defaultValue,
|
|
18310
|
+
sampleData: config3.sampleData
|
|
18311
|
+
};
|
|
18312
|
+
}
|
|
18313
|
+
function normalizeConditionalConfig(config3) {
|
|
18314
|
+
validateConfig(config3, "conditional");
|
|
18315
|
+
validateString(config3.condition, "condition", "conditional", true);
|
|
18316
|
+
const trueSteps = config3.trueSteps ?? config3.true_steps;
|
|
18317
|
+
const falseSteps = config3.falseSteps ?? config3.false_steps;
|
|
18318
|
+
if (trueSteps) {
|
|
18319
|
+
validateArray(trueSteps, "trueSteps", "conditional");
|
|
18320
|
+
}
|
|
18321
|
+
if (falseSteps) {
|
|
18322
|
+
validateArray(falseSteps, "falseSteps", "conditional");
|
|
18323
|
+
}
|
|
18324
|
+
const normalizeNestedSteps = (steps, parentStepId = "conditional") => {
|
|
18325
|
+
return steps.map((step, index) => {
|
|
18326
|
+
const stepWithDefaults = {
|
|
18327
|
+
...step,
|
|
18328
|
+
id: step.id || `${parentStepId}-nested-${index}-${Date.now()}`,
|
|
18329
|
+
order: step.order ?? index
|
|
18330
|
+
};
|
|
18331
|
+
if (step.type === "prompt") {
|
|
18332
|
+
return stepWithDefaults;
|
|
18333
|
+
}
|
|
18334
|
+
return normalizeContextStep(stepWithDefaults);
|
|
18335
|
+
});
|
|
18336
|
+
};
|
|
18337
|
+
return {
|
|
18338
|
+
condition: config3.condition,
|
|
18339
|
+
trueSteps: trueSteps ? normalizeNestedSteps(trueSteps, "conditional-true") : [],
|
|
18340
|
+
falseSteps: falseSteps ? normalizeNestedSteps(falseSteps, "conditional-false") : void 0
|
|
18341
|
+
};
|
|
18342
|
+
}
|
|
18343
|
+
function normalizeSetVariableConfig(config3) {
|
|
18344
|
+
validateConfig(config3, "set-variable");
|
|
18345
|
+
const variableName = config3.variableName ?? config3.variable_name;
|
|
18346
|
+
validateString(variableName, "variableName", "set-variable", true);
|
|
18347
|
+
if (config3.value === void 0) {
|
|
18348
|
+
throw new NormalizationError(
|
|
18349
|
+
`Missing required field 'value' for set-variable step`,
|
|
18350
|
+
"set-variable",
|
|
18351
|
+
"value",
|
|
18352
|
+
"any value",
|
|
18353
|
+
void 0
|
|
18354
|
+
);
|
|
18355
|
+
}
|
|
18356
|
+
if (config3.valueTemplate !== void 0 && config3.valueTemplate !== null) {
|
|
18357
|
+
validateString(config3.valueTemplate, "valueTemplate", "set-variable");
|
|
18358
|
+
}
|
|
18359
|
+
return {
|
|
18360
|
+
variableName,
|
|
18361
|
+
value: config3.value,
|
|
18362
|
+
valueTemplate: config3.valueTemplate
|
|
18363
|
+
};
|
|
18364
|
+
}
|
|
18365
|
+
function normalizeUpsertRecordConfig(config3) {
|
|
18366
|
+
validateConfig(config3, "upsert-record");
|
|
18367
|
+
validateString(config3.recordType, "recordType", "upsert-record", true);
|
|
18368
|
+
validateString(config3.sourceVariable, "sourceVariable", "upsert-record", true);
|
|
18369
|
+
validateString(config3.outputVariable, "outputVariable", "upsert-record", true);
|
|
18370
|
+
if (config3.recordName !== void 0 && config3.recordName !== null) {
|
|
18371
|
+
validateString(config3.recordName, "recordName", "upsert-record");
|
|
18372
|
+
}
|
|
18373
|
+
if (config3.mergeStrategy) {
|
|
18374
|
+
validateEnum(config3.mergeStrategy, ["merge", "replace"], "mergeStrategy", "upsert-record");
|
|
18375
|
+
}
|
|
18376
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18377
|
+
config3.errorHandling,
|
|
18378
|
+
"errorHandling",
|
|
18379
|
+
"upsert-record"
|
|
18380
|
+
);
|
|
18381
|
+
if (config3.inputMode) {
|
|
18382
|
+
validateEnum(config3.inputMode, ["single", "batch"], "inputMode", "upsert-record");
|
|
18383
|
+
}
|
|
18384
|
+
return {
|
|
18385
|
+
recordType: config3.recordType,
|
|
18386
|
+
recordName: config3.recordName,
|
|
18387
|
+
sourceVariable: config3.sourceVariable,
|
|
18388
|
+
outputVariable: config3.outputVariable,
|
|
18389
|
+
mergeStrategy: config3.mergeStrategy,
|
|
18390
|
+
errorHandling,
|
|
18391
|
+
defaultValue: config3.defaultValue,
|
|
18392
|
+
// Batch mode
|
|
18393
|
+
inputMode: config3.inputMode,
|
|
18394
|
+
inputVariable: config3.inputVariable,
|
|
18395
|
+
itemAlias: config3.itemAlias,
|
|
18396
|
+
metadataMapping: config3.metadataMapping,
|
|
18397
|
+
batchSize: config3.batchSize
|
|
18398
|
+
};
|
|
18399
|
+
}
|
|
18400
|
+
function normalizeSendEmailConfig(config3, options = {}) {
|
|
18401
|
+
validateConfig(config3, "send-email");
|
|
18402
|
+
validateString(config3.from, "from", "send-email");
|
|
18403
|
+
validateString(config3.to, "to", "send-email", true);
|
|
18404
|
+
validateString(config3.subject, "subject", "send-email", true);
|
|
18405
|
+
if (isCustomSendFromAddressOnManagedDomain(config3.from, options.managedSendFromDomain)) {
|
|
18406
|
+
throw new NormalizationError(
|
|
18407
|
+
"Field 'from' cannot use the platform-managed email domain for a custom sender",
|
|
18408
|
+
"send-email",
|
|
18409
|
+
"from",
|
|
18410
|
+
"custom email address on a non-managed domain",
|
|
18411
|
+
config3.from
|
|
18412
|
+
);
|
|
18413
|
+
}
|
|
18414
|
+
validateString(config3.outputVariable, "outputVariable", "send-email", true);
|
|
18415
|
+
if (config3.replyTo) validateString(config3.replyTo, "replyTo", "send-email");
|
|
18416
|
+
if (config3.cc) validateString(config3.cc, "cc", "send-email");
|
|
18417
|
+
if (config3.bcc) validateString(config3.bcc, "bcc", "send-email");
|
|
18418
|
+
if (config3.html) validateString(config3.html, "html", "send-email");
|
|
18419
|
+
if (config3.text) validateString(config3.text, "text", "send-email");
|
|
18420
|
+
if (config3.attachments) {
|
|
18421
|
+
validateArray(config3.attachments, "attachments", "send-email");
|
|
18422
|
+
}
|
|
18423
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18424
|
+
config3.errorHandling,
|
|
18425
|
+
"errorHandling",
|
|
18426
|
+
"send-email"
|
|
18427
|
+
);
|
|
18428
|
+
return {
|
|
18429
|
+
from: config3.from,
|
|
18430
|
+
to: config3.to,
|
|
18431
|
+
subject: config3.subject,
|
|
18432
|
+
replyTo: config3.replyTo,
|
|
18433
|
+
cc: config3.cc,
|
|
18434
|
+
bcc: config3.bcc,
|
|
18435
|
+
html: config3.html,
|
|
18436
|
+
text: config3.text,
|
|
18437
|
+
attachments: config3.attachments,
|
|
18438
|
+
outputVariable: config3.outputVariable,
|
|
18439
|
+
errorHandling,
|
|
18440
|
+
defaultValue: config3.defaultValue
|
|
18441
|
+
};
|
|
18442
|
+
}
|
|
18443
|
+
function normalizeSendTextConfig(config3) {
|
|
18444
|
+
validateConfig(config3, "send-text");
|
|
18445
|
+
validateString(config3.from, "from", "send-text", true);
|
|
18446
|
+
validateString(config3.to, "to", "send-text", true);
|
|
18447
|
+
validateString(config3.message, "message", "send-text", true);
|
|
18448
|
+
validateString(config3.outputVariable, "outputVariable", "send-text", true);
|
|
18449
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18450
|
+
config3.errorHandling,
|
|
18451
|
+
"errorHandling",
|
|
18452
|
+
"send-text"
|
|
18453
|
+
);
|
|
18454
|
+
return {
|
|
18455
|
+
from: config3.from,
|
|
18456
|
+
to: config3.to,
|
|
18457
|
+
message: config3.message,
|
|
18458
|
+
outputVariable: config3.outputVariable,
|
|
18459
|
+
errorHandling,
|
|
18460
|
+
defaultValue: config3.defaultValue
|
|
18461
|
+
};
|
|
18462
|
+
}
|
|
18463
|
+
function normalizeSendEventConfig(config3) {
|
|
18464
|
+
validateConfig(config3, "send-event");
|
|
18465
|
+
validateEnum(
|
|
18466
|
+
config3.provider,
|
|
18467
|
+
["posthog", "google-analytics", "amplitude", "segment"],
|
|
18468
|
+
"provider",
|
|
18469
|
+
"send-event",
|
|
18470
|
+
true
|
|
18471
|
+
);
|
|
18472
|
+
validateString(config3.eventName, "eventName", "send-event", true);
|
|
18473
|
+
validateString(config3.outputVariable, "outputVariable", "send-event", true);
|
|
18474
|
+
if (config3.properties !== void 0 && config3.properties !== null) {
|
|
18475
|
+
validateObject(config3.properties, "properties", "send-event");
|
|
18476
|
+
}
|
|
18477
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18478
|
+
config3.errorHandling,
|
|
18479
|
+
"errorHandling",
|
|
18480
|
+
"send-event"
|
|
18481
|
+
);
|
|
18482
|
+
return {
|
|
18483
|
+
provider: config3.provider,
|
|
18484
|
+
eventName: config3.eventName,
|
|
18485
|
+
properties: config3.properties,
|
|
18486
|
+
// Preserve user property keys as-is
|
|
18487
|
+
outputVariable: config3.outputVariable,
|
|
18488
|
+
errorHandling,
|
|
18489
|
+
defaultValue: config3.defaultValue
|
|
18490
|
+
};
|
|
18491
|
+
}
|
|
18492
|
+
function normalizeSendStreamConfig(config3) {
|
|
18493
|
+
validateConfig(config3, "send-stream");
|
|
18494
|
+
validateString(config3.message, "message", "send-stream", true);
|
|
18495
|
+
return {
|
|
18496
|
+
message: config3.message
|
|
18497
|
+
};
|
|
18498
|
+
}
|
|
18499
|
+
function normalizeUpdateRecordConfig(config3) {
|
|
18500
|
+
validateConfig(config3, "update-record");
|
|
18501
|
+
const filter = config3.recordFilter;
|
|
18502
|
+
const hasFilter = filter && typeof filter === "object" && typeof filter.type === "string" && filter.type.length > 0;
|
|
18503
|
+
if (!config3.recordId && !(config3.recordType && config3.recordName) && !hasFilter) {
|
|
18504
|
+
throw new NormalizationError(
|
|
18505
|
+
`update-record step requires either 'recordId', both 'recordType' and 'recordName', or 'recordFilter'`,
|
|
18506
|
+
"update-record",
|
|
18507
|
+
"recordId/recordType/recordName/recordFilter",
|
|
18508
|
+
"at least one identification method",
|
|
18509
|
+
void 0
|
|
18510
|
+
);
|
|
18511
|
+
}
|
|
18512
|
+
validateObject(config3.updates, "updates", "update-record", true);
|
|
18513
|
+
validateString(config3.outputVariable, "outputVariable", "update-record", true);
|
|
18514
|
+
validateEnum(
|
|
18515
|
+
config3.mergeStrategy,
|
|
18516
|
+
["merge", "replace", "deep-merge"],
|
|
18517
|
+
"mergeStrategy",
|
|
18518
|
+
"update-record",
|
|
18519
|
+
true
|
|
18520
|
+
);
|
|
18521
|
+
if (config3.updatesTemplate !== void 0 && config3.updatesTemplate !== null) {
|
|
18522
|
+
validateString(config3.updatesTemplate, "updatesTemplate", "update-record");
|
|
18523
|
+
}
|
|
18524
|
+
if (config3.includeFullRecord !== void 0 && config3.includeFullRecord !== null) {
|
|
18525
|
+
validateBoolean(config3.includeFullRecord, "includeFullRecord", "update-record");
|
|
18526
|
+
}
|
|
18527
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18528
|
+
config3.errorHandling,
|
|
18529
|
+
"errorHandling",
|
|
18530
|
+
"update-record"
|
|
18531
|
+
);
|
|
18532
|
+
return {
|
|
18533
|
+
recordId: config3.recordId,
|
|
18534
|
+
recordType: config3.recordType,
|
|
18535
|
+
recordName: config3.recordName,
|
|
18536
|
+
recordFilter: config3.recordFilter,
|
|
18537
|
+
updates: config3.updates,
|
|
18538
|
+
// Preserve user metadata keys as-is
|
|
18539
|
+
updatesTemplate: config3.updatesTemplate,
|
|
18540
|
+
mergeStrategy: config3.mergeStrategy,
|
|
18541
|
+
outputVariable: config3.outputVariable,
|
|
18542
|
+
includeFullRecord: config3.includeFullRecord,
|
|
18543
|
+
errorHandling,
|
|
18544
|
+
defaultValue: config3.defaultValue
|
|
18545
|
+
};
|
|
18546
|
+
}
|
|
18547
|
+
function normalizeSearchConfig(config3) {
|
|
18548
|
+
validateConfig(config3, "search");
|
|
18549
|
+
validateString(config3.provider, "provider", "search", true);
|
|
18550
|
+
validateString(config3.query, "query", "search", true);
|
|
18551
|
+
validateString(config3.outputVariable, "outputVariable", "search", true);
|
|
18552
|
+
if (config3.maxResults !== void 0 && config3.maxResults !== null) {
|
|
18553
|
+
validateNumber(config3.maxResults, "maxResults", "search");
|
|
18554
|
+
}
|
|
18555
|
+
if (config3.maxTokens !== void 0 && config3.maxTokens !== null) {
|
|
18556
|
+
validateNumber(config3.maxTokens, "maxTokens", "search");
|
|
18557
|
+
}
|
|
18558
|
+
if (config3.temperature !== void 0 && config3.temperature !== null) {
|
|
18559
|
+
validateNumber(config3.temperature, "temperature", "search");
|
|
18560
|
+
}
|
|
18561
|
+
if (config3.returnCitations !== void 0 && config3.returnCitations !== null) {
|
|
18562
|
+
validateBoolean(config3.returnCitations, "returnCitations", "search");
|
|
18563
|
+
}
|
|
18564
|
+
if (config3.allowedDomains) validateArray(config3.allowedDomains, "allowedDomains", "search");
|
|
18565
|
+
if (config3.blockedDomains) validateArray(config3.blockedDomains, "blockedDomains", "search");
|
|
18566
|
+
if (config3.sources) validateArray(config3.sources, "sources", "search");
|
|
18567
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18568
|
+
config3.errorHandling,
|
|
18569
|
+
"errorHandling",
|
|
18570
|
+
"search"
|
|
18571
|
+
);
|
|
18572
|
+
return {
|
|
18573
|
+
provider: config3.provider,
|
|
18574
|
+
query: config3.query,
|
|
18575
|
+
maxResults: config3.maxResults,
|
|
18576
|
+
returnCitations: config3.returnCitations,
|
|
18577
|
+
dateRange: config3.dateRange,
|
|
18578
|
+
allowedDomains: config3.allowedDomains,
|
|
18579
|
+
blockedDomains: config3.blockedDomains,
|
|
18580
|
+
userLocation: config3.userLocation,
|
|
18581
|
+
sources: config3.sources,
|
|
18582
|
+
temperature: config3.temperature,
|
|
18583
|
+
maxTokens: config3.maxTokens,
|
|
18584
|
+
// Exa-specific options
|
|
18585
|
+
exaSearchType: config3.exaSearchType,
|
|
18586
|
+
exaContents: config3.exaContents,
|
|
18587
|
+
exaCategory: config3.exaCategory,
|
|
18588
|
+
outputVariable: config3.outputVariable,
|
|
18589
|
+
errorHandling,
|
|
18590
|
+
defaultValue: config3.defaultValue
|
|
18591
|
+
};
|
|
18592
|
+
}
|
|
18593
|
+
function normalizeGenerateEmbeddingConfig(config3) {
|
|
18594
|
+
validateConfig(config3, "generate-embedding");
|
|
18595
|
+
const isBatchMode = config3.inputMode === "batch";
|
|
18596
|
+
validateString(config3.outputVariable, "outputVariable", "generate-embedding", true);
|
|
18597
|
+
if (isBatchMode) {
|
|
18598
|
+
validateString(config3.inputVariable, "inputVariable", "generate-embedding", true);
|
|
18599
|
+
if (config3.textTemplate)
|
|
18600
|
+
validateString(config3.textTemplate, "textTemplate", "generate-embedding");
|
|
18601
|
+
if (config3.itemAlias) validateString(config3.itemAlias, "itemAlias", "generate-embedding");
|
|
18602
|
+
if (config3.batchSize !== void 0 && config3.batchSize !== null) {
|
|
18603
|
+
validateNumber(config3.batchSize, "batchSize", "generate-embedding");
|
|
18604
|
+
}
|
|
18605
|
+
} else {
|
|
18606
|
+
validateEnum(
|
|
18607
|
+
config3.inputSource,
|
|
18608
|
+
["text", "variable", "record"],
|
|
18609
|
+
"inputSource",
|
|
18610
|
+
"generate-embedding",
|
|
18611
|
+
true
|
|
18612
|
+
);
|
|
18613
|
+
if (config3.inputSource === "text") {
|
|
18614
|
+
if (config3.text !== void 0 && config3.text !== null) {
|
|
18615
|
+
validateString(config3.text, "text", "generate-embedding");
|
|
18616
|
+
}
|
|
18617
|
+
} else if (config3.inputSource === "variable") {
|
|
18618
|
+
validateString(config3.variableName, "variableName", "generate-embedding", true);
|
|
18619
|
+
} else if (config3.inputSource === "record") {
|
|
18620
|
+
if (!config3.recordId && !(config3.recordType && config3.recordName)) {
|
|
18621
|
+
throw new NormalizationError(
|
|
18622
|
+
`generate-embedding step with inputSource='record' requires either 'recordId' or both 'recordType' and 'recordName'`,
|
|
18623
|
+
"generate-embedding",
|
|
18624
|
+
"recordId/recordType/recordName",
|
|
18625
|
+
"at least one identification method",
|
|
18626
|
+
void 0
|
|
18627
|
+
);
|
|
18628
|
+
}
|
|
18629
|
+
}
|
|
18630
|
+
}
|
|
18631
|
+
if (config3.embeddingModel)
|
|
18632
|
+
validateString(config3.embeddingModel, "embeddingModel", "generate-embedding");
|
|
18633
|
+
if (config3.textField) validateString(config3.textField, "textField", "generate-embedding");
|
|
18634
|
+
if (config3.maxLength !== void 0 && config3.maxLength !== null) {
|
|
18635
|
+
validateNumber(config3.maxLength, "maxLength", "generate-embedding");
|
|
18636
|
+
}
|
|
18637
|
+
if (config3.storeInRecord !== void 0 && config3.storeInRecord !== null) {
|
|
18638
|
+
validateBoolean(config3.storeInRecord, "storeInRecord", "generate-embedding");
|
|
18639
|
+
}
|
|
18640
|
+
return {
|
|
18641
|
+
inputSource: config3.inputSource,
|
|
18642
|
+
text: config3.text,
|
|
18643
|
+
variableName: config3.variableName,
|
|
18644
|
+
recordId: config3.recordId,
|
|
18645
|
+
recordType: config3.recordType,
|
|
18646
|
+
recordName: config3.recordName,
|
|
18647
|
+
textField: config3.textField,
|
|
18648
|
+
storeInRecord: config3.storeInRecord,
|
|
18649
|
+
embeddingModel: config3.embeddingModel,
|
|
18650
|
+
maxLength: config3.maxLength,
|
|
18651
|
+
outputVariable: config3.outputVariable,
|
|
18652
|
+
streamOutput: config3.streamOutput,
|
|
18653
|
+
// Batch mode fields
|
|
18654
|
+
inputMode: config3.inputMode,
|
|
18655
|
+
inputVariable: config3.inputVariable,
|
|
18656
|
+
textTemplate: config3.textTemplate,
|
|
18657
|
+
itemAlias: config3.itemAlias,
|
|
18658
|
+
batchSize: config3.batchSize
|
|
18659
|
+
};
|
|
18660
|
+
}
|
|
18661
|
+
function normalizeVectorSearchConfig(config3) {
|
|
18662
|
+
validateConfig(config3, "vector-search");
|
|
18663
|
+
validateString(config3.query, "query", "vector-search", true);
|
|
18664
|
+
validateString(config3.outputVariable, "outputVariable", "vector-search", true);
|
|
18665
|
+
if (config3.embeddingModel)
|
|
18666
|
+
validateString(config3.embeddingModel, "embeddingModel", "vector-search");
|
|
18667
|
+
if (config3.limit !== void 0 && config3.limit !== null) {
|
|
18668
|
+
validateNumber(config3.limit, "limit", "vector-search");
|
|
18669
|
+
}
|
|
18670
|
+
if (config3.threshold !== void 0 && config3.threshold !== null) {
|
|
18671
|
+
validateNumber(config3.threshold, "threshold", "vector-search");
|
|
18672
|
+
}
|
|
18673
|
+
if (config3.recordType) validateString(config3.recordType, "recordType", "vector-search");
|
|
18674
|
+
if (config3.metadataFilters !== void 0 && config3.metadataFilters !== null) {
|
|
18675
|
+
validateObject(config3.metadataFilters, "metadataFilters", "vector-search");
|
|
18676
|
+
}
|
|
18677
|
+
if (config3.includeEmbedding !== void 0 && config3.includeEmbedding !== null) {
|
|
18678
|
+
validateBoolean(config3.includeEmbedding, "includeEmbedding", "vector-search");
|
|
18679
|
+
}
|
|
18680
|
+
const providerInput = config3.provider || config3.vectorStore || "record";
|
|
18681
|
+
const vectorStore = providerInput === "record" ? "pgvector" : providerInput;
|
|
18682
|
+
const vectorizeConfig = config3.vectorizeConfigId || config3.vectorizeNamespace ? {
|
|
18683
|
+
configId: config3.vectorizeConfigId,
|
|
18684
|
+
namespace: config3.vectorizeNamespace
|
|
18685
|
+
} : void 0;
|
|
18686
|
+
const weaviateConfig = config3.weaviateClassName || config3.weaviateConfigId ? {
|
|
18687
|
+
configId: config3.weaviateConfigId,
|
|
18688
|
+
className: config3.weaviateClassName || ""
|
|
18689
|
+
} : void 0;
|
|
18690
|
+
return {
|
|
18691
|
+
query: config3.query,
|
|
18692
|
+
embeddingModel: config3.embeddingModel,
|
|
18693
|
+
limit: config3.limit,
|
|
18694
|
+
threshold: config3.threshold,
|
|
18695
|
+
recordType: config3.recordType,
|
|
18696
|
+
metadataFilters: config3.metadataFilters,
|
|
18697
|
+
// Preserve user filter keys
|
|
18698
|
+
outputVariable: config3.outputVariable,
|
|
18699
|
+
includeEmbedding: config3.includeEmbedding,
|
|
18700
|
+
streamOutput: config3.streamOutput,
|
|
18701
|
+
// Provider selection and provider-specific config (typed fields)
|
|
18702
|
+
vectorStore,
|
|
18703
|
+
vectorizeConfig,
|
|
18704
|
+
weaviateConfig,
|
|
18705
|
+
// Also pass through flat fields for executor compatibility
|
|
18706
|
+
// These are used by the executor which checks both patterns
|
|
18707
|
+
provider: providerInput,
|
|
18708
|
+
// Keep original for executor
|
|
18709
|
+
vectorizeConfigId: config3.vectorizeConfigId,
|
|
18710
|
+
vectorizeNamespace: config3.vectorizeNamespace,
|
|
18711
|
+
weaviateClassName: config3.weaviateClassName,
|
|
18712
|
+
hybridSearch: config3.hybridSearch,
|
|
18713
|
+
hybridAlpha: config3.hybridAlpha,
|
|
18714
|
+
weaviateProperties: config3.weaviateProperties
|
|
18715
|
+
};
|
|
18716
|
+
}
|
|
18717
|
+
function normalizePaginateApiConfig(config3) {
|
|
18718
|
+
validateConfig(config3, "paginate-api");
|
|
18719
|
+
const url2 = config3.http?.url || config3.url;
|
|
18720
|
+
validateString(url2, "url", "paginate-api", true);
|
|
18721
|
+
const method = config3.http?.method || config3.method || "GET";
|
|
18722
|
+
validateEnum(method, ["GET", "POST"], "method", "paginate-api");
|
|
18723
|
+
const headers = config3.http?.headers ?? config3.headers;
|
|
18724
|
+
if (headers !== void 0 && headers !== null) {
|
|
18725
|
+
validateObject(headers, "headers", "paginate-api");
|
|
18726
|
+
}
|
|
18727
|
+
const body = config3.http?.body ?? config3.body;
|
|
18728
|
+
if (body !== void 0 && body !== null) {
|
|
18729
|
+
validateString(body, "body", "paginate-api");
|
|
18730
|
+
}
|
|
18731
|
+
const paginationType = config3.paginationType || "offset";
|
|
18732
|
+
validateEnum(
|
|
18733
|
+
paginationType,
|
|
18734
|
+
["cursor", "offset", "page", "link_header"],
|
|
18735
|
+
"paginationType",
|
|
18736
|
+
"paginate-api",
|
|
18737
|
+
true
|
|
18738
|
+
);
|
|
18739
|
+
const pageSizeRaw = config3.pageSize;
|
|
18740
|
+
const pageSize = pageSizeRaw !== void 0 && pageSizeRaw !== null ? Number(pageSizeRaw) : 100;
|
|
18741
|
+
if (pageSizeRaw !== void 0 && pageSizeRaw !== null) {
|
|
18742
|
+
validateNumber(pageSizeRaw, "pageSize", "paginate-api");
|
|
18743
|
+
}
|
|
18744
|
+
const paginationConfigInput = config3.paginationConfig || {};
|
|
18745
|
+
if (paginationConfigInput !== void 0 && paginationConfigInput !== null) {
|
|
18746
|
+
validateObject(paginationConfigInput, "paginationConfig", "paginate-api");
|
|
18747
|
+
}
|
|
18748
|
+
const paginationConfig = { ...paginationConfigInput };
|
|
18749
|
+
if (paginationType === "cursor") {
|
|
18750
|
+
paginationConfig.cursorParam = paginationConfig.cursorParam || config3.cursorParam || "cursor";
|
|
18751
|
+
paginationConfig.cursorPath = paginationConfig.cursorPath || config3.cursorPath;
|
|
18752
|
+
} else if (paginationType === "offset") {
|
|
18753
|
+
paginationConfig.offsetParam = paginationConfig.offsetParam || config3.offsetParam || "offset";
|
|
18754
|
+
paginationConfig.limitParam = paginationConfig.limitParam || config3.limitParam || "limit";
|
|
18755
|
+
paginationConfig.limit = paginationConfig.limit ?? pageSize;
|
|
18756
|
+
paginationConfig.totalPath = paginationConfig.totalPath || config3.totalPath;
|
|
18757
|
+
} else if (paginationType === "page") {
|
|
18758
|
+
paginationConfig.pageParam = paginationConfig.pageParam || config3.pageParam || "page";
|
|
18759
|
+
paginationConfig.perPageParam = paginationConfig.perPageParam || config3.perPageParam || "per_page";
|
|
18760
|
+
paginationConfig.perPage = paginationConfig.perPage ?? pageSize;
|
|
18761
|
+
paginationConfig.totalPagesPath = paginationConfig.totalPagesPath || config3.totalPagesPath;
|
|
18762
|
+
}
|
|
18763
|
+
const entitiesPath = config3.entitiesPath || config3.entityPath || "$[*]";
|
|
18764
|
+
validateString(entitiesPath, "entitiesPath", "paginate-api", true);
|
|
18765
|
+
const outputVariable = config3.outputVariable || "entities";
|
|
18766
|
+
validateString(outputVariable, "outputVariable", "paginate-api", true);
|
|
18767
|
+
if (config3.maxPages !== void 0 && config3.maxPages !== null) {
|
|
18768
|
+
validateNumber(config3.maxPages, "maxPages", "paginate-api");
|
|
18769
|
+
}
|
|
18770
|
+
if (config3.maxEntities !== void 0 && config3.maxEntities !== null) {
|
|
18771
|
+
validateNumber(config3.maxEntities, "maxEntities", "paginate-api");
|
|
18772
|
+
}
|
|
18773
|
+
if (config3.requestDelayMs !== void 0 && config3.requestDelayMs !== null) {
|
|
18774
|
+
validateNumber(config3.requestDelayMs, "requestDelayMs", "paginate-api");
|
|
18775
|
+
}
|
|
18776
|
+
if (config3.retryOnRateLimit !== void 0 && config3.retryOnRateLimit !== null) {
|
|
18777
|
+
validateBoolean(config3.retryOnRateLimit, "retryOnRateLimit", "paginate-api");
|
|
18778
|
+
}
|
|
18779
|
+
if (config3.maxRetries !== void 0 && config3.maxRetries !== null) {
|
|
18780
|
+
validateNumber(config3.maxRetries, "maxRetries", "paginate-api");
|
|
18781
|
+
}
|
|
18782
|
+
if (config3.includeMetadata !== void 0 && config3.includeMetadata !== null) {
|
|
18783
|
+
validateBoolean(config3.includeMetadata, "includeMetadata", "paginate-api");
|
|
18784
|
+
}
|
|
18785
|
+
if (config3.streamOutput !== void 0 && config3.streamOutput !== null) {
|
|
18786
|
+
validateBoolean(config3.streamOutput, "streamOutput", "paginate-api");
|
|
18787
|
+
}
|
|
18788
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18789
|
+
config3.errorHandling,
|
|
18790
|
+
"errorHandling",
|
|
18791
|
+
"paginate-api"
|
|
18792
|
+
);
|
|
18793
|
+
return {
|
|
18794
|
+
url: url2,
|
|
18795
|
+
method,
|
|
18796
|
+
headers,
|
|
18797
|
+
body,
|
|
18798
|
+
authType: config3.authType || "none",
|
|
18799
|
+
authConfig: config3.authConfig,
|
|
18800
|
+
paginationType,
|
|
18801
|
+
paginationConfig,
|
|
18802
|
+
pageSize,
|
|
18803
|
+
maxPages: config3.maxPages,
|
|
18804
|
+
offsetParam: config3.offsetParam,
|
|
18805
|
+
limitParam: config3.limitParam,
|
|
18806
|
+
cursorParam: config3.cursorParam,
|
|
18807
|
+
cursorPath: config3.cursorPath,
|
|
18808
|
+
pageParam: config3.pageParam,
|
|
18809
|
+
startPage: config3.startPage,
|
|
18810
|
+
entitiesPath,
|
|
18811
|
+
entityPath: config3.entityPath,
|
|
18812
|
+
entityIdPath: config3.entityIdPath,
|
|
18813
|
+
maxEntities: config3.maxEntities,
|
|
18814
|
+
requestDelayMs: config3.requestDelayMs,
|
|
18815
|
+
retryOnRateLimit: config3.retryOnRateLimit,
|
|
18816
|
+
maxRetries: config3.maxRetries,
|
|
18817
|
+
outputVariable,
|
|
18818
|
+
includeMetadata: config3.includeMetadata,
|
|
18819
|
+
streamOutput: config3.streamOutput,
|
|
18820
|
+
errorHandling,
|
|
18821
|
+
defaultValue: config3.defaultValue
|
|
18822
|
+
};
|
|
18823
|
+
}
|
|
18824
|
+
function normalizeStoreVectorConfig(config3) {
|
|
18825
|
+
validateConfig(config3, "store-vector");
|
|
18826
|
+
const destination = config3.destination;
|
|
18827
|
+
validateEnum(
|
|
18828
|
+
destination,
|
|
18829
|
+
["pgvector", "weaviate", "vectorize", "pinecone"],
|
|
18830
|
+
"destination",
|
|
18831
|
+
"store-vector",
|
|
18832
|
+
true
|
|
18833
|
+
);
|
|
18834
|
+
if (config3.vectorsSource) {
|
|
18835
|
+
validateString(config3.vectorsSource, "vectorsSource", "store-vector");
|
|
18836
|
+
}
|
|
18837
|
+
if (config3.inputMode) {
|
|
18838
|
+
validateEnum(config3.inputMode, ["single", "batch"], "inputMode", "store-vector");
|
|
18839
|
+
}
|
|
18840
|
+
if (config3.outputVariable) {
|
|
18841
|
+
validateString(config3.outputVariable, "outputVariable", "store-vector");
|
|
18842
|
+
}
|
|
18843
|
+
if (config3.streamOutput !== void 0 && config3.streamOutput !== null) {
|
|
18844
|
+
validateBoolean(config3.streamOutput, "streamOutput", "store-vector");
|
|
18845
|
+
}
|
|
18846
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
18847
|
+
config3.errorHandling,
|
|
18848
|
+
"errorHandling",
|
|
18849
|
+
"store-vector"
|
|
18850
|
+
);
|
|
18851
|
+
const idTemplate = config3.idTemplate;
|
|
18852
|
+
const metadata = config3.metadata;
|
|
18853
|
+
const weaviateConfigInput = config3.weaviateConfig;
|
|
18854
|
+
const vectorizeConfigInput = config3.vectorizeConfig;
|
|
18855
|
+
const pineconeConfig = config3.pineconeConfig;
|
|
18856
|
+
const weaviateConfigId = config3.weaviateConfigId;
|
|
18857
|
+
const weaviateClassName = config3.weaviateClassName;
|
|
18858
|
+
const vectorizeConfigId = config3.vectorizeConfigId;
|
|
18859
|
+
const vectorizeNamespace = config3.vectorizeNamespace;
|
|
18860
|
+
const normalizedWeaviateConfig = weaviateConfigInput || (weaviateConfigId || weaviateClassName || metadata || idTemplate ? {
|
|
18861
|
+
configId: weaviateConfigId,
|
|
18862
|
+
className: weaviateClassName,
|
|
18863
|
+
uuid: idTemplate,
|
|
18864
|
+
properties: metadata
|
|
18865
|
+
} : void 0);
|
|
18866
|
+
const normalizedVectorizeConfig = vectorizeConfigInput || (vectorizeConfigId || vectorizeNamespace || metadata || idTemplate ? {
|
|
18867
|
+
configId: vectorizeConfigId,
|
|
18868
|
+
id: idTemplate,
|
|
18869
|
+
namespace: vectorizeNamespace,
|
|
18870
|
+
metadata
|
|
18871
|
+
} : void 0);
|
|
18872
|
+
return {
|
|
18873
|
+
vectorsSource: config3.vectorsSource,
|
|
18874
|
+
inputMode: config3.inputMode,
|
|
18875
|
+
inputVariable: config3.inputVariable,
|
|
18876
|
+
itemAlias: config3.itemAlias,
|
|
18877
|
+
batchSize: config3.batchSize,
|
|
18878
|
+
destination,
|
|
18879
|
+
weaviateConfig: normalizedWeaviateConfig,
|
|
18880
|
+
vectorizeConfig: normalizedVectorizeConfig,
|
|
18881
|
+
pineconeConfig,
|
|
18882
|
+
weaviateConfigId,
|
|
18883
|
+
weaviateClassName,
|
|
18884
|
+
vectorizeConfigId,
|
|
18885
|
+
vectorizeNamespace,
|
|
18886
|
+
pineconeConfigId: config3.pineconeConfigId,
|
|
18887
|
+
pineconeNamespace: config3.pineconeNamespace,
|
|
18888
|
+
idTemplate,
|
|
18889
|
+
metadata,
|
|
18890
|
+
outputVariable: config3.outputVariable,
|
|
18891
|
+
streamOutput: config3.streamOutput,
|
|
18892
|
+
errorHandling,
|
|
18893
|
+
defaultValue: config3.defaultValue
|
|
18894
|
+
};
|
|
18895
|
+
}
|
|
18896
|
+
function normalizeToolCallConfig(config3) {
|
|
18897
|
+
validateConfig(config3, "tool-call");
|
|
18898
|
+
validateString(config3.toolId, "toolId", "tool-call", true);
|
|
18899
|
+
validateObject(config3.parameters, "parameters", "tool-call", true);
|
|
18900
|
+
validateString(config3.outputVariable, "outputVariable", "tool-call", true);
|
|
18901
|
+
if (config3.maxRetries !== void 0 && config3.maxRetries !== null) {
|
|
18902
|
+
validateNumber(config3.maxRetries, "maxRetries", "tool-call");
|
|
18903
|
+
}
|
|
18904
|
+
if (config3.timeout !== void 0 && config3.timeout !== null) {
|
|
18905
|
+
validateNumber(config3.timeout, "timeout", "tool-call");
|
|
18906
|
+
}
|
|
18907
|
+
if (config3.onError) {
|
|
18908
|
+
validateEnum(config3.onError, ["fail", "continue", "retry"], "onError", "tool-call");
|
|
18909
|
+
}
|
|
18910
|
+
return {
|
|
18911
|
+
toolId: config3.toolId,
|
|
18912
|
+
parameters: config3.parameters,
|
|
18913
|
+
// Preserve user parameter keys as-is
|
|
18914
|
+
outputVariable: config3.outputVariable,
|
|
18915
|
+
maxRetries: config3.maxRetries,
|
|
18916
|
+
timeout: config3.timeout,
|
|
18917
|
+
onError: config3.onError
|
|
18918
|
+
};
|
|
18919
|
+
}
|
|
18920
|
+
function normalizeSuccessCriteria(criteria) {
|
|
18921
|
+
if (!criteria) return void 0;
|
|
18922
|
+
validateObject(criteria, "poll.success", "wait-until", true);
|
|
18923
|
+
if (criteria.type) {
|
|
18924
|
+
validateEnum(
|
|
18925
|
+
criteria.type,
|
|
18926
|
+
["status", "json_path", "body_contains", "expression"],
|
|
18927
|
+
"poll.success.type",
|
|
18928
|
+
"wait-until"
|
|
18929
|
+
);
|
|
18930
|
+
}
|
|
18931
|
+
if (criteria.status !== void 0 && criteria.status !== null) {
|
|
18932
|
+
validateNumber(criteria.status, "poll.success.status", "wait-until");
|
|
18933
|
+
}
|
|
18934
|
+
if (criteria.jsonPath) validateString(criteria.jsonPath, "poll.success.jsonPath", "wait-until");
|
|
18935
|
+
if (criteria.bodyContains)
|
|
18936
|
+
validateString(criteria.bodyContains, "poll.success.bodyContains", "wait-until");
|
|
18937
|
+
if (criteria.expression)
|
|
18938
|
+
validateString(criteria.expression, "poll.success.expression", "wait-until");
|
|
18939
|
+
return {
|
|
18940
|
+
type: criteria.type,
|
|
18941
|
+
status: criteria.status,
|
|
18942
|
+
jsonPath: criteria.jsonPath,
|
|
18943
|
+
expectedValue: criteria.expectedValue,
|
|
18944
|
+
operator: criteria.operator,
|
|
18945
|
+
bodyContains: criteria.bodyContains,
|
|
18946
|
+
expression: criteria.expression
|
|
18947
|
+
};
|
|
18948
|
+
}
|
|
18949
|
+
function normalizePollConfig(poll) {
|
|
18950
|
+
if (!poll) return void 0;
|
|
18951
|
+
validateObject(poll, "poll", "wait-until", true);
|
|
18952
|
+
if (poll.enabled === false) {
|
|
18953
|
+
const httpConfig = poll.http ? {
|
|
18954
|
+
url: poll.http.url || "",
|
|
18955
|
+
method: poll.http.method,
|
|
18956
|
+
headers: poll.http.headers,
|
|
18957
|
+
body: poll.http.body,
|
|
18958
|
+
timeout: poll.http.timeout
|
|
18959
|
+
} : { url: "" };
|
|
18960
|
+
return {
|
|
18961
|
+
enabled: false,
|
|
18962
|
+
http: httpConfig,
|
|
18963
|
+
auth: poll.auth ? normalizeAuthConfig(poll.auth) : void 0,
|
|
18964
|
+
intervalMs: poll.intervalMs,
|
|
18965
|
+
maxAttempts: poll.maxAttempts,
|
|
18966
|
+
responseType: poll.responseType,
|
|
18967
|
+
success: normalizeSuccessCriteria(poll.success)
|
|
18968
|
+
};
|
|
18969
|
+
}
|
|
18970
|
+
validateObject(poll.http, "poll.http", "wait-until", true);
|
|
18971
|
+
if (poll.intervalMs !== void 0 && poll.intervalMs !== null) {
|
|
18972
|
+
if (typeof poll.intervalMs !== "string") {
|
|
18973
|
+
validateNumber(poll.intervalMs, "poll.intervalMs", "wait-until");
|
|
18974
|
+
}
|
|
18975
|
+
}
|
|
18976
|
+
if (poll.maxAttempts !== void 0 && poll.maxAttempts !== null) {
|
|
18977
|
+
validateNumber(poll.maxAttempts, "poll.maxAttempts", "wait-until");
|
|
18978
|
+
}
|
|
18979
|
+
if (poll.responseType) {
|
|
18980
|
+
validateEnum(poll.responseType, ["json", "text"], "poll.responseType", "wait-until");
|
|
18981
|
+
}
|
|
18982
|
+
if (poll.enabled !== void 0 && poll.enabled !== null) {
|
|
18983
|
+
validateBoolean(poll.enabled, "poll.enabled", "wait-until");
|
|
18984
|
+
}
|
|
18985
|
+
return {
|
|
18986
|
+
enabled: poll.enabled,
|
|
18987
|
+
http: normalizeHttpConfig(poll.http),
|
|
18988
|
+
auth: normalizeAuthConfig(poll.auth),
|
|
18989
|
+
intervalMs: poll.intervalMs,
|
|
18990
|
+
maxAttempts: poll.maxAttempts,
|
|
18991
|
+
responseType: poll.responseType,
|
|
18992
|
+
success: normalizeSuccessCriteria(poll.success)
|
|
18993
|
+
};
|
|
18994
|
+
}
|
|
18995
|
+
function normalizeWaitUntilConfig(config3) {
|
|
18996
|
+
validateConfig(config3, "wait-until");
|
|
18997
|
+
validateString(config3.outputVariable, "outputVariable", "wait-until", true);
|
|
18998
|
+
if (config3.delayMs === void 0 && !config3.poll) {
|
|
18999
|
+
throw new NormalizationError(
|
|
19000
|
+
`wait-until step requires either 'delayMs' or 'poll' configuration`,
|
|
19001
|
+
"wait-until",
|
|
19002
|
+
"delayMs/poll",
|
|
19003
|
+
"at least one wait mechanism",
|
|
19004
|
+
void 0
|
|
19005
|
+
);
|
|
19006
|
+
}
|
|
19007
|
+
if (config3.delayMs !== void 0 && config3.delayMs !== null) {
|
|
19008
|
+
if (typeof config3.delayMs !== "string") {
|
|
19009
|
+
validateNumber(config3.delayMs, "delayMs", "wait-until");
|
|
19010
|
+
}
|
|
19011
|
+
}
|
|
19012
|
+
if (config3.continueOnTimeout !== void 0 && config3.continueOnTimeout !== null) {
|
|
19013
|
+
validateBoolean(config3.continueOnTimeout, "continueOnTimeout", "wait-until");
|
|
19014
|
+
}
|
|
19015
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19016
|
+
config3.errorHandling,
|
|
19017
|
+
"errorHandling",
|
|
19018
|
+
"wait-until"
|
|
19019
|
+
);
|
|
19020
|
+
return {
|
|
19021
|
+
delayMs: config3.delayMs,
|
|
19022
|
+
poll: normalizePollConfig(config3.poll),
|
|
19023
|
+
continueOnTimeout: config3.continueOnTimeout,
|
|
19024
|
+
errorHandling,
|
|
19025
|
+
defaultValue: config3.defaultValue,
|
|
19026
|
+
outputVariable: config3.outputVariable
|
|
19027
|
+
};
|
|
19028
|
+
}
|
|
19029
|
+
function normalizeExecuteAgentConfig(config3) {
|
|
19030
|
+
validateConfig(config3, "execute-agent");
|
|
19031
|
+
const agentId = config3.agentId ?? config3.agent_id;
|
|
19032
|
+
validateString(agentId, "agentId", "execute-agent", true);
|
|
19033
|
+
const message = config3.message;
|
|
19034
|
+
validateString(message, "message", "execute-agent", true);
|
|
19035
|
+
const outputVariable = config3.outputVariable ?? config3.output_variable ?? "agent_response";
|
|
19036
|
+
validateString(outputVariable, "outputVariable", "execute-agent");
|
|
19037
|
+
const maxTurns = config3.maxTurns ?? config3.max_turns;
|
|
19038
|
+
if (maxTurns !== void 0 && maxTurns !== null) {
|
|
19039
|
+
validateNumber(maxTurns, "maxTurns", "execute-agent");
|
|
19040
|
+
}
|
|
19041
|
+
if (config3.timeout !== void 0 && config3.timeout !== null) {
|
|
19042
|
+
validateNumber(config3.timeout, "timeout", "execute-agent");
|
|
19043
|
+
}
|
|
19044
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19045
|
+
config3.errorHandling ?? config3.error_handling,
|
|
19046
|
+
"errorHandling",
|
|
19047
|
+
"execute-agent"
|
|
19048
|
+
);
|
|
19049
|
+
return {
|
|
19050
|
+
agentId,
|
|
19051
|
+
message,
|
|
19052
|
+
outputVariable,
|
|
19053
|
+
variables: config3.variables,
|
|
19054
|
+
maxTurns,
|
|
19055
|
+
timeout: config3.timeout,
|
|
19056
|
+
errorHandling,
|
|
19057
|
+
defaultValue: config3.defaultValue ?? config3.default_value
|
|
19058
|
+
};
|
|
19059
|
+
}
|
|
19060
|
+
function normalizeStoreAssetConfig(config3) {
|
|
19061
|
+
validateConfig(config3, "store-asset");
|
|
19062
|
+
const url2 = config3.url;
|
|
19063
|
+
const content = config3.content;
|
|
19064
|
+
if ((url2 === void 0 || url2 === null) && (content === void 0 || content === null)) {
|
|
19065
|
+
throw new NormalizationError(
|
|
19066
|
+
'store-asset requires either "url" or "content" (base64)',
|
|
19067
|
+
"store-asset",
|
|
19068
|
+
"url",
|
|
19069
|
+
"string",
|
|
19070
|
+
void 0
|
|
19071
|
+
);
|
|
19072
|
+
}
|
|
19073
|
+
if (url2 !== void 0 && url2 !== null && content !== void 0 && content !== null) {
|
|
19074
|
+
throw new NormalizationError(
|
|
19075
|
+
'store-asset accepts exactly one of "url" or "content", not both',
|
|
19076
|
+
"store-asset",
|
|
19077
|
+
"url",
|
|
19078
|
+
"string",
|
|
19079
|
+
typeof url2
|
|
19080
|
+
);
|
|
19081
|
+
}
|
|
19082
|
+
if (url2 !== void 0 && url2 !== null) {
|
|
19083
|
+
validateString(url2, "url", "store-asset", true);
|
|
19084
|
+
}
|
|
19085
|
+
if (content !== void 0 && content !== null) {
|
|
19086
|
+
validateString(content, "content", "store-asset", true);
|
|
19087
|
+
}
|
|
19088
|
+
if (config3.filename !== void 0 && config3.filename !== null) {
|
|
19089
|
+
validateString(config3.filename, "filename", "store-asset");
|
|
19090
|
+
}
|
|
19091
|
+
if (config3.contentType !== void 0 && config3.contentType !== null) {
|
|
19092
|
+
validateString(config3.contentType, "contentType", "store-asset");
|
|
19093
|
+
}
|
|
19094
|
+
if (config3.visibility !== void 0 && config3.visibility !== null) {
|
|
19095
|
+
validateEnum(config3.visibility, ["public", "private"], "visibility", "store-asset");
|
|
19096
|
+
}
|
|
19097
|
+
validateString(config3.outputVariable, "outputVariable", "store-asset", true);
|
|
19098
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19099
|
+
config3.errorHandling,
|
|
19100
|
+
"errorHandling",
|
|
19101
|
+
"store-asset"
|
|
19102
|
+
);
|
|
19103
|
+
return {
|
|
19104
|
+
url: url2,
|
|
19105
|
+
content,
|
|
19106
|
+
filename: config3.filename,
|
|
19107
|
+
contentType: config3.contentType,
|
|
19108
|
+
visibility: config3.visibility,
|
|
19109
|
+
outputVariable: config3.outputVariable,
|
|
19110
|
+
streamOutput: config3.streamOutput,
|
|
19111
|
+
errorHandling,
|
|
19112
|
+
defaultValue: config3.defaultValue
|
|
19113
|
+
};
|
|
19114
|
+
}
|
|
19115
|
+
function normalizeGeneratePdfConfig(config3) {
|
|
19116
|
+
validateConfig(config3, "generate-pdf");
|
|
19117
|
+
const html = config3.html;
|
|
19118
|
+
const markdown = config3.markdown;
|
|
19119
|
+
if ((html === void 0 || html === null) && (markdown === void 0 || markdown === null)) {
|
|
19120
|
+
throw new NormalizationError(
|
|
19121
|
+
'generate-pdf requires either "html" or "markdown"',
|
|
19122
|
+
"generate-pdf",
|
|
19123
|
+
"html",
|
|
19124
|
+
"string",
|
|
19125
|
+
void 0
|
|
19126
|
+
);
|
|
19127
|
+
}
|
|
19128
|
+
if (html !== void 0 && html !== null && markdown !== void 0 && markdown !== null) {
|
|
19129
|
+
throw new NormalizationError(
|
|
19130
|
+
'generate-pdf accepts exactly one of "html" or "markdown", not both',
|
|
19131
|
+
"generate-pdf",
|
|
19132
|
+
"html",
|
|
19133
|
+
"string",
|
|
19134
|
+
typeof html
|
|
19135
|
+
);
|
|
19136
|
+
}
|
|
19137
|
+
if (html !== void 0 && html !== null) {
|
|
19138
|
+
validateString(html, "html", "generate-pdf", true);
|
|
19139
|
+
}
|
|
19140
|
+
if (markdown !== void 0 && markdown !== null) {
|
|
19141
|
+
validateString(markdown, "markdown", "generate-pdf", true);
|
|
19142
|
+
}
|
|
19143
|
+
if (config3.filename !== void 0 && config3.filename !== null) {
|
|
19144
|
+
validateString(config3.filename, "filename", "generate-pdf");
|
|
19145
|
+
}
|
|
19146
|
+
if (config3.visibility !== void 0 && config3.visibility !== null) {
|
|
19147
|
+
validateEnum(config3.visibility, ["public", "private"], "visibility", "generate-pdf");
|
|
19148
|
+
}
|
|
19149
|
+
if (config3.pdfOptions !== void 0 && config3.pdfOptions !== null) {
|
|
19150
|
+
validateObject(config3.pdfOptions, "pdfOptions", "generate-pdf");
|
|
19151
|
+
const pdfOptions = config3.pdfOptions;
|
|
19152
|
+
if (pdfOptions.format !== void 0 && pdfOptions.format !== null) {
|
|
19153
|
+
validateEnum(pdfOptions.format, ["A4", "Letter"], "pdfOptions.format", "generate-pdf");
|
|
19154
|
+
}
|
|
19155
|
+
if (pdfOptions.landscape !== void 0 && pdfOptions.landscape !== null) {
|
|
19156
|
+
validateBoolean(pdfOptions.landscape, "pdfOptions.landscape", "generate-pdf");
|
|
19157
|
+
}
|
|
19158
|
+
}
|
|
19159
|
+
validateString(config3.outputVariable, "outputVariable", "generate-pdf", true);
|
|
19160
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19161
|
+
config3.errorHandling,
|
|
19162
|
+
"errorHandling",
|
|
19163
|
+
"generate-pdf"
|
|
19164
|
+
);
|
|
19165
|
+
return {
|
|
19166
|
+
html,
|
|
19167
|
+
markdown,
|
|
19168
|
+
filename: config3.filename,
|
|
19169
|
+
visibility: config3.visibility,
|
|
19170
|
+
pdfOptions: config3.pdfOptions,
|
|
19171
|
+
outputVariable: config3.outputVariable,
|
|
19172
|
+
streamOutput: config3.streamOutput,
|
|
19173
|
+
errorHandling,
|
|
19174
|
+
defaultValue: config3.defaultValue
|
|
19175
|
+
};
|
|
19176
|
+
}
|
|
19177
|
+
function normalizeSaveMemoryConfig(config3) {
|
|
19178
|
+
validateConfig(config3, "save-memory");
|
|
19179
|
+
validateString(config3.profileTemplate, "profileTemplate", "save-memory", true);
|
|
19180
|
+
validateString(config3.contentVariable, "contentVariable", "save-memory", true);
|
|
19181
|
+
if (config3.sessionId !== void 0 && config3.sessionId !== null) {
|
|
19182
|
+
validateString(config3.sessionId, "sessionId", "save-memory");
|
|
19183
|
+
}
|
|
19184
|
+
if (config3.outputVariable !== void 0 && config3.outputVariable !== null) {
|
|
19185
|
+
validateString(config3.outputVariable, "outputVariable", "save-memory");
|
|
19186
|
+
}
|
|
19187
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19188
|
+
config3.errorHandling ?? config3.error_handling,
|
|
19189
|
+
"errorHandling",
|
|
19190
|
+
"save-memory"
|
|
19191
|
+
);
|
|
19192
|
+
return {
|
|
19193
|
+
profileTemplate: config3.profileTemplate,
|
|
19194
|
+
contentVariable: config3.contentVariable,
|
|
19195
|
+
sessionId: config3.sessionId,
|
|
19196
|
+
outputVariable: config3.outputVariable,
|
|
19197
|
+
errorHandling,
|
|
19198
|
+
defaultValue: config3.defaultValue ?? config3.default_value
|
|
19199
|
+
};
|
|
19200
|
+
}
|
|
19201
|
+
function normalizeRecallMemoryConfig(config3) {
|
|
19202
|
+
validateConfig(config3, "recall-memory");
|
|
19203
|
+
validateString(config3.profileTemplate, "profileTemplate", "recall-memory", true);
|
|
19204
|
+
validateString(config3.queryTemplate, "queryTemplate", "recall-memory", true);
|
|
19205
|
+
validateString(config3.outputVariable, "outputVariable", "recall-memory", true);
|
|
19206
|
+
validateEnum(config3.thinkingLevel, ["low", "medium", "high"], "thinkingLevel", "recall-memory");
|
|
19207
|
+
validateEnum(
|
|
19208
|
+
config3.responseLength,
|
|
19209
|
+
["short", "medium", "long"],
|
|
19210
|
+
"responseLength",
|
|
19211
|
+
"recall-memory"
|
|
19212
|
+
);
|
|
19213
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19214
|
+
config3.errorHandling ?? config3.error_handling,
|
|
19215
|
+
"errorHandling",
|
|
19216
|
+
"recall-memory"
|
|
19217
|
+
);
|
|
19218
|
+
return {
|
|
19219
|
+
profileTemplate: config3.profileTemplate,
|
|
19220
|
+
queryTemplate: config3.queryTemplate,
|
|
19221
|
+
thinkingLevel: config3.thinkingLevel,
|
|
19222
|
+
responseLength: config3.responseLength,
|
|
19223
|
+
outputVariable: config3.outputVariable,
|
|
19224
|
+
errorHandling,
|
|
19225
|
+
defaultValue: config3.defaultValue ?? config3.default_value
|
|
19226
|
+
};
|
|
19227
|
+
}
|
|
19228
|
+
function normalizeMemorySummaryConfig(config3) {
|
|
19229
|
+
validateConfig(config3, "memory-summary");
|
|
19230
|
+
validateString(config3.profileTemplate, "profileTemplate", "memory-summary", true);
|
|
19231
|
+
validateString(config3.outputVariable, "outputVariable", "memory-summary", true);
|
|
19232
|
+
if (config3.sessionId !== void 0 && config3.sessionId !== null) {
|
|
19233
|
+
validateString(config3.sessionId, "sessionId", "memory-summary");
|
|
19234
|
+
}
|
|
19235
|
+
const errorHandling = validateAndNormalizeErrorHandling(
|
|
19236
|
+
config3.errorHandling ?? config3.error_handling,
|
|
19237
|
+
"errorHandling",
|
|
19238
|
+
"memory-summary"
|
|
19239
|
+
);
|
|
19240
|
+
return {
|
|
19241
|
+
profileTemplate: config3.profileTemplate,
|
|
19242
|
+
sessionId: config3.sessionId,
|
|
19243
|
+
outputVariable: config3.outputVariable,
|
|
19244
|
+
errorHandling,
|
|
19245
|
+
defaultValue: config3.defaultValue ?? config3.default_value
|
|
19246
|
+
};
|
|
19247
|
+
}
|
|
19248
|
+
var NAMED_AGENT_REF_PREFIX = "agent:";
|
|
19249
|
+
var NAMED_FLOW_REF_PREFIX = "flow:";
|
|
19250
|
+
function isNamedRef(value, prefix) {
|
|
19251
|
+
return value.startsWith(prefix) && value.length > prefix.length;
|
|
19252
|
+
}
|
|
19253
|
+
function parseNamedRef(value, prefix) {
|
|
19254
|
+
if (!isNamedRef(value, prefix)) return null;
|
|
19255
|
+
return { name: value.slice(prefix.length) };
|
|
19256
|
+
}
|
|
19257
|
+
function parseNamedAgentRef(value) {
|
|
19258
|
+
return parseNamedRef(value, NAMED_AGENT_REF_PREFIX);
|
|
19259
|
+
}
|
|
19260
|
+
function parseNamedFlowRef(value) {
|
|
19261
|
+
return parseNamedRef(value, NAMED_FLOW_REF_PREFIX);
|
|
19262
|
+
}
|
|
19263
|
+
function sanitizeCodeToolIdentifier(name) {
|
|
19264
|
+
let safe = name.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
19265
|
+
if (/^[0-9]/.test(safe)) safe = "_" + safe;
|
|
19266
|
+
return safe;
|
|
19267
|
+
}
|
|
17250
19268
|
var flowStepValidationSchema = external_exports.object({
|
|
17251
19269
|
// Optional stable client-supplied identifier. Preserved across saves so that
|
|
17252
19270
|
// `flow_step_results.stepId` references stay valid and dashboard UI state
|
|
@@ -17306,6 +19324,1102 @@ var KNOWN_TOOL_KEYS = /* @__PURE__ */ new Set([
|
|
|
17306
19324
|
...Object.keys(CAMEL_CASE_TOOL_KEYS),
|
|
17307
19325
|
...Object.keys(SNAKE_CASE_TOOL_KEYS)
|
|
17308
19326
|
]);
|
|
19327
|
+
var LEGACY_TOOL_KEY_SUGGESTIONS = {
|
|
19328
|
+
builtinTools: "toolIds"
|
|
19329
|
+
};
|
|
19330
|
+
function isObjectRecord(value) {
|
|
19331
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19332
|
+
}
|
|
19333
|
+
var NETWORK_ISOLATED_SANDBOX_PROVIDERS = /* @__PURE__ */ new Set(["cloudflare-worker", "quickjs"]);
|
|
19334
|
+
var MAX_CONDITIONAL_NESTING_DEPTH = 10;
|
|
19335
|
+
var FETCH_CALL_PATTERN = /\bfetch\s*\(/;
|
|
19336
|
+
function validateSandboxNetworkAccess(config3, stepIndex, stepRef, buckets) {
|
|
19337
|
+
const rawProvider = typeof config3.sandboxProvider === "string" ? config3.sandboxProvider : "cloudflare-worker";
|
|
19338
|
+
if (!NETWORK_ISOLATED_SANDBOX_PROVIDERS.has(rawProvider)) {
|
|
19339
|
+
return;
|
|
19340
|
+
}
|
|
19341
|
+
const networkAccess = config3.networkAccess;
|
|
19342
|
+
if (networkAccess === "on") {
|
|
19343
|
+
return;
|
|
19344
|
+
}
|
|
19345
|
+
if (isObjectRecord(networkAccess) && Array.isArray(networkAccess.allowedHostnames) && networkAccess.allowedHostnames.length > 0) {
|
|
19346
|
+
return;
|
|
19347
|
+
}
|
|
19348
|
+
const code = typeof config3.script === "string" ? config3.script : "";
|
|
19349
|
+
if (!code || !FETCH_CALL_PATTERN.test(code)) {
|
|
19350
|
+
return;
|
|
19351
|
+
}
|
|
19352
|
+
addIssue(
|
|
19353
|
+
"warning",
|
|
19354
|
+
{
|
|
19355
|
+
code: "SANDBOX_NETWORK_ACCESS_DISABLED",
|
|
19356
|
+
message: "Step uses fetch() but network access is disabled for this sandbox; the request will be blocked at runtime. Set networkAccess to 'on' or an allowedHostnames allowlist, or use the daytona provider.",
|
|
19357
|
+
path: `flowSteps[${stepIndex}].config.networkAccess`,
|
|
19358
|
+
step: stepRef,
|
|
19359
|
+
details: {
|
|
19360
|
+
sandboxProvider: rawProvider,
|
|
19361
|
+
networkAccess: typeof networkAccess === "string" ? networkAccess : "off"
|
|
19362
|
+
}
|
|
19363
|
+
},
|
|
19364
|
+
buckets
|
|
19365
|
+
);
|
|
19366
|
+
}
|
|
19367
|
+
function validateCodeToolNameCollisions(toolNames, stepRef, code, preSeededCount = 0) {
|
|
19368
|
+
const seen = /* @__PURE__ */ new Map();
|
|
19369
|
+
for (const [i, tool] of toolNames.entries()) {
|
|
19370
|
+
const sanitized = sanitizeCodeToolIdentifier(tool.name);
|
|
19371
|
+
if (i < preSeededCount) {
|
|
19372
|
+
seen.set(sanitized, tool);
|
|
19373
|
+
continue;
|
|
19374
|
+
}
|
|
19375
|
+
const existing = seen.get(sanitized);
|
|
19376
|
+
if (existing) {
|
|
19377
|
+
return {
|
|
19378
|
+
code,
|
|
19379
|
+
message: `Tool names "${existing.name}" and "${tool.name}" both become "${sanitized}" in JavaScript. Rename or remove one before enabling code-mode execution.`,
|
|
19380
|
+
path: tool.path,
|
|
19381
|
+
step: stepRef,
|
|
19382
|
+
details: {
|
|
19383
|
+
firstPath: existing.path,
|
|
19384
|
+
secondPath: tool.path,
|
|
19385
|
+
sanitizedName: sanitized
|
|
19386
|
+
}
|
|
19387
|
+
};
|
|
19388
|
+
}
|
|
19389
|
+
seen.set(sanitized, tool);
|
|
19390
|
+
}
|
|
19391
|
+
return null;
|
|
19392
|
+
}
|
|
19393
|
+
function formatPath(path18) {
|
|
19394
|
+
return path18.reduce((acc, part) => {
|
|
19395
|
+
if (typeof part === "number") {
|
|
19396
|
+
return `${acc}[${part}]`;
|
|
19397
|
+
}
|
|
19398
|
+
const key = String(part);
|
|
19399
|
+
return acc ? `${acc}.${key}` : key;
|
|
19400
|
+
}, "");
|
|
19401
|
+
}
|
|
19402
|
+
function compareIssuePath(a, b) {
|
|
19403
|
+
if (!a && !b) return 0;
|
|
19404
|
+
if (!a) return 1;
|
|
19405
|
+
if (!b) return -1;
|
|
19406
|
+
return a.localeCompare(b);
|
|
19407
|
+
}
|
|
19408
|
+
function sortIssues(issues) {
|
|
19409
|
+
return [...issues].sort((a, b) => {
|
|
19410
|
+
const aStepIndex = a.step?.index ?? Number.MAX_SAFE_INTEGER;
|
|
19411
|
+
const bStepIndex = b.step?.index ?? Number.MAX_SAFE_INTEGER;
|
|
19412
|
+
if (aStepIndex !== bStepIndex) {
|
|
19413
|
+
return aStepIndex - bStepIndex;
|
|
19414
|
+
}
|
|
19415
|
+
const pathCompare = compareIssuePath(a.path, b.path);
|
|
19416
|
+
if (pathCompare !== 0) {
|
|
19417
|
+
return pathCompare;
|
|
19418
|
+
}
|
|
19419
|
+
const codeCompare = a.code.localeCompare(b.code);
|
|
19420
|
+
if (codeCompare !== 0) {
|
|
19421
|
+
return codeCompare;
|
|
19422
|
+
}
|
|
19423
|
+
return a.message.localeCompare(b.message);
|
|
19424
|
+
});
|
|
19425
|
+
}
|
|
19426
|
+
function addIssue(level, issue2, buckets) {
|
|
19427
|
+
switch (level) {
|
|
19428
|
+
case "error":
|
|
19429
|
+
buckets.errors.push(issue2);
|
|
19430
|
+
return;
|
|
19431
|
+
case "warning":
|
|
19432
|
+
buckets.warnings.push(issue2);
|
|
19433
|
+
return;
|
|
19434
|
+
default:
|
|
19435
|
+
buckets.recommendations.push(issue2);
|
|
19436
|
+
}
|
|
19437
|
+
}
|
|
19438
|
+
function buildIssueFromZod(issue2, resolvedPath, step) {
|
|
19439
|
+
return {
|
|
19440
|
+
code: "SCHEMA_VALIDATION_FAILED",
|
|
19441
|
+
message: issue2.message,
|
|
19442
|
+
path: resolvedPath,
|
|
19443
|
+
step,
|
|
19444
|
+
details: issue2
|
|
19445
|
+
};
|
|
19446
|
+
}
|
|
19447
|
+
function conditionalNestingDepth(config3) {
|
|
19448
|
+
let maxDepth = 0;
|
|
19449
|
+
const stack = [{ node: config3, depth: 1 }];
|
|
19450
|
+
while (stack.length > 0) {
|
|
19451
|
+
const { node, depth } = stack.pop();
|
|
19452
|
+
if (depth > maxDepth) maxDepth = depth;
|
|
19453
|
+
if (depth > MAX_CONDITIONAL_NESTING_DEPTH) break;
|
|
19454
|
+
if (!node || typeof node !== "object") continue;
|
|
19455
|
+
const cfg = node;
|
|
19456
|
+
for (const key of ["trueSteps", "falseSteps", "true_steps", "false_steps"]) {
|
|
19457
|
+
const branch = cfg[key];
|
|
19458
|
+
if (!Array.isArray(branch)) continue;
|
|
19459
|
+
for (const s of branch) {
|
|
19460
|
+
if (s && typeof s === "object" && s.type === "conditional") {
|
|
19461
|
+
const nestedCfg = s.config;
|
|
19462
|
+
if (nestedCfg && typeof nestedCfg === "object") {
|
|
19463
|
+
stack.push({ node: nestedCfg, depth: depth + 1 });
|
|
19464
|
+
}
|
|
19465
|
+
}
|
|
19466
|
+
}
|
|
19467
|
+
}
|
|
19468
|
+
}
|
|
19469
|
+
return maxDepth;
|
|
19470
|
+
}
|
|
19471
|
+
function registerReference(map2, id, reference) {
|
|
19472
|
+
const existing = map2.get(id) || [];
|
|
19473
|
+
existing.push(reference);
|
|
19474
|
+
map2.set(id, existing);
|
|
19475
|
+
}
|
|
19476
|
+
function collectRuntimeToolNameSelections(toolsConfig, stepIndex, selectedNames) {
|
|
19477
|
+
const runtimeTools = Array.isArray(toolsConfig.runtimeTools) ? toolsConfig.runtimeTools : [];
|
|
19478
|
+
const selections = [];
|
|
19479
|
+
for (const [runtimeToolIndex, runtimeTool] of runtimeTools.entries()) {
|
|
19480
|
+
if (!isObjectRecord(runtimeTool)) {
|
|
19481
|
+
continue;
|
|
19482
|
+
}
|
|
19483
|
+
const name = runtimeTool.name;
|
|
19484
|
+
if (typeof name !== "string") {
|
|
19485
|
+
continue;
|
|
19486
|
+
}
|
|
19487
|
+
if (selectedNames && !selectedNames.has(name)) {
|
|
19488
|
+
continue;
|
|
19489
|
+
}
|
|
19490
|
+
selections.push({
|
|
19491
|
+
name,
|
|
19492
|
+
path: `flowSteps[${stepIndex}].config.tools.runtimeTools[${runtimeToolIndex}].name`
|
|
19493
|
+
});
|
|
19494
|
+
}
|
|
19495
|
+
return selections;
|
|
19496
|
+
}
|
|
19497
|
+
function collectTransformDataCodeToolNameCheck(toolsConfig, stepIndex, stepRef, pendingChecks) {
|
|
19498
|
+
const toolIds = Array.isArray(toolsConfig.toolIds) ? toolsConfig.toolIds : [];
|
|
19499
|
+
const selectedToolIds = [];
|
|
19500
|
+
const selectedToolNames = [];
|
|
19501
|
+
for (const [toolIdIndex, toolId] of toolIds.entries()) {
|
|
19502
|
+
if (typeof toolId !== "string") {
|
|
19503
|
+
continue;
|
|
19504
|
+
}
|
|
19505
|
+
const path18 = `flowSteps[${stepIndex}].config.tools.toolIds[${toolIdIndex}]`;
|
|
19506
|
+
const named = parseNamedToolRef(toolId);
|
|
19507
|
+
if (named) {
|
|
19508
|
+
selectedToolNames.push({ name: named.name, path: path18 });
|
|
19509
|
+
continue;
|
|
19510
|
+
}
|
|
19511
|
+
const { customToolIds } = separateToolIds([toolId]);
|
|
19512
|
+
if (customToolIds.length === 0) {
|
|
19513
|
+
continue;
|
|
19514
|
+
}
|
|
19515
|
+
selectedToolIds.push({ toolId, path: path18 });
|
|
19516
|
+
}
|
|
19517
|
+
if (selectedToolIds.length > 0 || selectedToolNames.length > 0) {
|
|
19518
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19519
|
+
pendingChecks.codeToolNameChecks.push({
|
|
19520
|
+
step: stepRef,
|
|
19521
|
+
collisionCode: "CODE_STEP_TOOL_NAME_COLLISION",
|
|
19522
|
+
runtimeToolNames: collectRuntimeToolNameSelections(toolsConfig, stepIndex),
|
|
19523
|
+
selectedToolIds,
|
|
19524
|
+
selectedToolNames
|
|
19525
|
+
});
|
|
19526
|
+
}
|
|
19527
|
+
}
|
|
19528
|
+
function collectCodeModeToolNameCheck(toolsConfig, stepIndex, stepRef, pendingChecks) {
|
|
19529
|
+
const codeModeConfig = toolsConfig.codeModeConfig;
|
|
19530
|
+
if (!isObjectRecord(codeModeConfig) || !Array.isArray(codeModeConfig.toolPool)) {
|
|
19531
|
+
return;
|
|
19532
|
+
}
|
|
19533
|
+
const runtimeTools = Array.isArray(toolsConfig.runtimeTools) ? toolsConfig.runtimeTools : [];
|
|
19534
|
+
const runtimeToolNames = /* @__PURE__ */ new Set();
|
|
19535
|
+
for (const runtimeTool of runtimeTools) {
|
|
19536
|
+
if (!isObjectRecord(runtimeTool) || typeof runtimeTool.name !== "string") {
|
|
19537
|
+
continue;
|
|
19538
|
+
}
|
|
19539
|
+
runtimeToolNames.add(runtimeTool.name);
|
|
19540
|
+
}
|
|
19541
|
+
const selectedRuntimeToolNames = /* @__PURE__ */ new Set();
|
|
19542
|
+
const selectedToolIds = [];
|
|
19543
|
+
const selectedToolNames = [];
|
|
19544
|
+
for (const [toolPoolIndex, entry] of codeModeConfig.toolPool.entries()) {
|
|
19545
|
+
if (typeof entry !== "string" || entry.length === 0 || entry.endsWith(":*")) {
|
|
19546
|
+
continue;
|
|
19547
|
+
}
|
|
19548
|
+
const path18 = `flowSteps[${stepIndex}].config.tools.codeModeConfig.toolPool[${toolPoolIndex}]`;
|
|
19549
|
+
const named = parseNamedToolRef(entry);
|
|
19550
|
+
if (named) {
|
|
19551
|
+
selectedToolNames.push({ name: named.name, path: path18 });
|
|
19552
|
+
continue;
|
|
19553
|
+
}
|
|
19554
|
+
if (runtimeToolNames.has(entry)) {
|
|
19555
|
+
selectedRuntimeToolNames.add(entry);
|
|
19556
|
+
continue;
|
|
19557
|
+
}
|
|
19558
|
+
const { customToolIds } = separateToolIds([entry]);
|
|
19559
|
+
if (customToolIds.length === 0) {
|
|
19560
|
+
continue;
|
|
19561
|
+
}
|
|
19562
|
+
selectedToolIds.push({ toolId: entry, path: path18 });
|
|
19563
|
+
}
|
|
19564
|
+
if (selectedToolIds.length > 0 || selectedToolNames.length > 0) {
|
|
19565
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19566
|
+
pendingChecks.codeToolNameChecks.push({
|
|
19567
|
+
step: stepRef,
|
|
19568
|
+
collisionCode: "CODE_MODE_TOOL_NAME_COLLISION",
|
|
19569
|
+
runtimeToolNames: collectRuntimeToolNameSelections(
|
|
19570
|
+
toolsConfig,
|
|
19571
|
+
stepIndex,
|
|
19572
|
+
selectedRuntimeToolNames
|
|
19573
|
+
),
|
|
19574
|
+
selectedToolIds,
|
|
19575
|
+
selectedToolNames
|
|
19576
|
+
});
|
|
19577
|
+
}
|
|
19578
|
+
}
|
|
19579
|
+
var SINGLE_BRACE_VARIABLE_PATTERN = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_.]*)\}(?!\})/g;
|
|
19580
|
+
var DOUBLE_BRACE_VARIABLE_PATTERN = TEMPLATE_EXPRESSION_PATTERN;
|
|
19581
|
+
var TEMPLATE_STRING_FIELDS = /* @__PURE__ */ new Set([
|
|
19582
|
+
"text",
|
|
19583
|
+
"userPrompt",
|
|
19584
|
+
"systemPrompt",
|
|
19585
|
+
"url",
|
|
19586
|
+
"body",
|
|
19587
|
+
"query",
|
|
19588
|
+
"message",
|
|
19589
|
+
"valueTemplate",
|
|
19590
|
+
"value",
|
|
19591
|
+
"subject",
|
|
19592
|
+
"html",
|
|
19593
|
+
"from",
|
|
19594
|
+
"to",
|
|
19595
|
+
"cc",
|
|
19596
|
+
"bcc",
|
|
19597
|
+
"replyTo",
|
|
19598
|
+
"nameTemplate",
|
|
19599
|
+
"condition",
|
|
19600
|
+
"script",
|
|
19601
|
+
"requestTemplate"
|
|
19602
|
+
]);
|
|
19603
|
+
var NON_FLOW_VARIABLE_SUBTREE_KEYS = /* @__PURE__ */ new Set(["tools"]);
|
|
19604
|
+
function extractTemplateStrings(config3, path18 = []) {
|
|
19605
|
+
const results = [];
|
|
19606
|
+
if (typeof config3 === "string") {
|
|
19607
|
+
const fieldName = path18[path18.length - 1];
|
|
19608
|
+
const parentFieldName = path18.length >= 2 ? path18[path18.length - 2] : void 0;
|
|
19609
|
+
if (fieldName && TEMPLATE_STRING_FIELDS.has(fieldName) || parentFieldName && TEMPLATE_STRING_FIELDS.has(parentFieldName)) {
|
|
19610
|
+
results.push({ value: config3, fieldPath: path18.join(".") });
|
|
19611
|
+
}
|
|
19612
|
+
return results;
|
|
19613
|
+
}
|
|
19614
|
+
if (Array.isArray(config3)) {
|
|
19615
|
+
for (const [index, item] of config3.entries()) {
|
|
19616
|
+
results.push(...extractTemplateStrings(item, [...path18, String(index)]));
|
|
19617
|
+
}
|
|
19618
|
+
return results;
|
|
19619
|
+
}
|
|
19620
|
+
if (isObjectRecord(config3)) {
|
|
19621
|
+
for (const [key, val] of Object.entries(config3)) {
|
|
19622
|
+
if (NON_FLOW_VARIABLE_SUBTREE_KEYS.has(key)) continue;
|
|
19623
|
+
if (typeof val === "string" && TEMPLATE_STRING_FIELDS.has(key)) {
|
|
19624
|
+
results.push({ value: val, fieldPath: [...path18, key].join(".") });
|
|
19625
|
+
} else if (typeof val === "object" && val !== null) {
|
|
19626
|
+
results.push(...extractTemplateStrings(val, [...path18, key]));
|
|
19627
|
+
}
|
|
19628
|
+
}
|
|
19629
|
+
}
|
|
19630
|
+
return results;
|
|
19631
|
+
}
|
|
19632
|
+
function detectMalformedVariableReferences(config3) {
|
|
19633
|
+
const malformed = [];
|
|
19634
|
+
const templateStrings = extractTemplateStrings(config3);
|
|
19635
|
+
for (const { value, fieldPath } of templateStrings) {
|
|
19636
|
+
let match;
|
|
19637
|
+
const pattern = new RegExp(SINGLE_BRACE_VARIABLE_PATTERN.source, "g");
|
|
19638
|
+
while ((match = pattern.exec(value)) !== null) {
|
|
19639
|
+
const varName = match[1];
|
|
19640
|
+
if (!varName) continue;
|
|
19641
|
+
const doublebraceForm = `{{${varName}}}`;
|
|
19642
|
+
if (value.includes(doublebraceForm)) continue;
|
|
19643
|
+
malformed.push({ variable: varName, fieldPath });
|
|
19644
|
+
}
|
|
19645
|
+
}
|
|
19646
|
+
return malformed;
|
|
19647
|
+
}
|
|
19648
|
+
function extractVariableReferences(config3) {
|
|
19649
|
+
const references = [];
|
|
19650
|
+
const templateStrings = extractTemplateStrings(config3);
|
|
19651
|
+
for (const { value, fieldPath } of templateStrings) {
|
|
19652
|
+
const pattern = new RegExp(DOUBLE_BRACE_VARIABLE_PATTERN.source, "g");
|
|
19653
|
+
let match;
|
|
19654
|
+
while ((match = pattern.exec(value)) !== null) {
|
|
19655
|
+
const expr = match[1];
|
|
19656
|
+
if (!expr) continue;
|
|
19657
|
+
for (const path18 of extractTemplateExpressionPaths(expr)) {
|
|
19658
|
+
references.push({ variable: path18, fieldPath });
|
|
19659
|
+
}
|
|
19660
|
+
}
|
|
19661
|
+
}
|
|
19662
|
+
return references;
|
|
19663
|
+
}
|
|
19664
|
+
function getStepOutputVariable(step) {
|
|
19665
|
+
if (!isObjectRecord(step.config)) return null;
|
|
19666
|
+
if (typeof step.config.outputVariable === "string" && step.config.outputVariable.length > 0) {
|
|
19667
|
+
return step.config.outputVariable;
|
|
19668
|
+
}
|
|
19669
|
+
if (step.type === "set-variable" && typeof step.config.variableName === "string" && step.config.variableName.length > 0) {
|
|
19670
|
+
return step.config.variableName;
|
|
19671
|
+
}
|
|
19672
|
+
return null;
|
|
19673
|
+
}
|
|
19674
|
+
function collectDeclaredFlowInputs(flowSteps, declaredFlowInputs) {
|
|
19675
|
+
const declared = /* @__PURE__ */ new Set();
|
|
19676
|
+
for (const key of declaredFlowInputs ?? []) {
|
|
19677
|
+
if (typeof key === "string" && key) declared.add(key);
|
|
19678
|
+
}
|
|
19679
|
+
for (const step of flowSteps) {
|
|
19680
|
+
const config3 = step.config;
|
|
19681
|
+
const inputVariables = config3?.inputVariables;
|
|
19682
|
+
if (Array.isArray(inputVariables)) {
|
|
19683
|
+
for (const name of inputVariables) {
|
|
19684
|
+
if (typeof name === "string" && name) declared.add(name);
|
|
19685
|
+
}
|
|
19686
|
+
}
|
|
19687
|
+
}
|
|
19688
|
+
return declared;
|
|
19689
|
+
}
|
|
19690
|
+
function validateVariableReferences(flowSteps, buckets, skipStepIndices, declaredFlowInputs) {
|
|
19691
|
+
const declaredVariables = collectDeclaredFlowInputs(flowSteps, declaredFlowInputs);
|
|
19692
|
+
for (const [stepIndex, step] of flowSteps.entries()) {
|
|
19693
|
+
if (skipStepIndices?.has(stepIndex)) continue;
|
|
19694
|
+
const stepRef = {
|
|
19695
|
+
index: stepIndex,
|
|
19696
|
+
name: step.name,
|
|
19697
|
+
type: step.type
|
|
19698
|
+
};
|
|
19699
|
+
const malformed = detectMalformedVariableReferences(step.config);
|
|
19700
|
+
for (const { variable, fieldPath } of malformed) {
|
|
19701
|
+
addIssue(
|
|
19702
|
+
"warning",
|
|
19703
|
+
{
|
|
19704
|
+
code: "MALFORMED_VARIABLE_REFERENCE",
|
|
19705
|
+
message: `Possible malformed variable reference "{${variable}}" \u2014 use "{{${variable}}}" for template variable substitution.`,
|
|
19706
|
+
path: `flowSteps[${stepIndex}].config.${fieldPath}`,
|
|
19707
|
+
step: stepRef,
|
|
19708
|
+
details: { variable, suggestion: `{{${variable}}}` }
|
|
19709
|
+
},
|
|
19710
|
+
buckets
|
|
19711
|
+
);
|
|
19712
|
+
}
|
|
19713
|
+
const references = extractVariableReferences(step.config);
|
|
19714
|
+
for (const { variable, fieldPath } of references) {
|
|
19715
|
+
const classification = classifyVariableReference(variable);
|
|
19716
|
+
if (classification.namespace === "system" || classification.namespace === "secret") {
|
|
19717
|
+
continue;
|
|
19718
|
+
}
|
|
19719
|
+
if (classification.namespace === "unknown") {
|
|
19720
|
+
addIssue(
|
|
19721
|
+
"warning",
|
|
19722
|
+
{
|
|
19723
|
+
code: "UNKNOWN_VARIABLE_NAMESPACE",
|
|
19724
|
+
message: `Variable "{{${variable}}}" uses an unrecognized namespace prefix. Recognized prefixes are "flow:" (a flow input) and "secret:" (a configured secret). Use a known prefix or a plain variable name.`,
|
|
19725
|
+
path: `flowSteps[${stepIndex}].config.${fieldPath}`,
|
|
19726
|
+
step: stepRef,
|
|
19727
|
+
details: { variable }
|
|
19728
|
+
},
|
|
19729
|
+
buckets
|
|
19730
|
+
);
|
|
19731
|
+
continue;
|
|
19732
|
+
}
|
|
19733
|
+
const baseName = classification.baseName;
|
|
19734
|
+
const rootVariable = baseName.split(".")[0] || "";
|
|
19735
|
+
if (!declaredVariables.has(rootVariable) && !declaredVariables.has(baseName)) {
|
|
19736
|
+
addIssue(
|
|
19737
|
+
"warning",
|
|
19738
|
+
{
|
|
19739
|
+
code: "UNDECLARED_VARIABLE_REFERENCE",
|
|
19740
|
+
message: `Variable "{{${variable}}}" is referenced but no earlier step declares an output variable "${rootVariable}". Check that a previous step sets outputVariable to "${rootVariable}", or declare "${rootVariable}" as a flow input.`,
|
|
19741
|
+
path: `flowSteps[${stepIndex}].config.${fieldPath}`,
|
|
19742
|
+
step: stepRef,
|
|
19743
|
+
details: {
|
|
19744
|
+
variable,
|
|
19745
|
+
availableVariables: [...declaredVariables]
|
|
19746
|
+
}
|
|
19747
|
+
},
|
|
19748
|
+
buckets
|
|
19749
|
+
);
|
|
19750
|
+
}
|
|
19751
|
+
}
|
|
19752
|
+
if (step.enabled !== false) {
|
|
19753
|
+
const outputVar = getStepOutputVariable(step);
|
|
19754
|
+
if (outputVar) {
|
|
19755
|
+
declaredVariables.add(outputVar);
|
|
19756
|
+
}
|
|
19757
|
+
}
|
|
19758
|
+
}
|
|
19759
|
+
}
|
|
19760
|
+
function promptResponseFormatIsNonJson(responseFormat) {
|
|
19761
|
+
if (typeof responseFormat !== "string") return true;
|
|
19762
|
+
return responseFormat.trim().toLowerCase() !== "json";
|
|
19763
|
+
}
|
|
19764
|
+
function validateUpsertRecordSourceShape(flowSteps, buckets) {
|
|
19765
|
+
const stringPromptOutputs = /* @__PURE__ */ new Map();
|
|
19766
|
+
for (const [stepIndex, step] of flowSteps.entries()) {
|
|
19767
|
+
if (step.enabled === false) continue;
|
|
19768
|
+
if (!isObjectRecord(step.config)) continue;
|
|
19769
|
+
const config3 = step.config;
|
|
19770
|
+
if (step.type === "upsert-record") {
|
|
19771
|
+
const inputMode = typeof config3.inputMode === "string" ? config3.inputMode : "single";
|
|
19772
|
+
const sourceVariable = typeof config3.sourceVariable === "string" ? config3.sourceVariable : "";
|
|
19773
|
+
const hasContentField = typeof config3.contentField === "string" && config3.contentField.length > 0;
|
|
19774
|
+
if (inputMode !== "batch" && sourceVariable && !hasContentField) {
|
|
19775
|
+
const origin = stringPromptOutputs.get(sourceVariable);
|
|
19776
|
+
if (origin) {
|
|
19777
|
+
addIssue(
|
|
19778
|
+
"warning",
|
|
19779
|
+
{
|
|
19780
|
+
code: "UPSERT_RECORD_SOURCE_NOT_JSON",
|
|
19781
|
+
message: `Source variable "${sourceVariable}" is set by prompt step "${origin.name}" (responseFormat "${origin.responseFormat}"), which outputs a string, but the record metadata column requires a JSON object. This will fail at runtime. Either: (1) set that prompt's responseFormat to "json", (2) add a transform-data step to wrap the string, or (3) set contentField on this upsert-record step to auto-wrap the string as { [contentField]: content }.`,
|
|
19782
|
+
path: `flowSteps[${stepIndex}].config.sourceVariable`,
|
|
19783
|
+
step: { index: stepIndex, name: step.name, type: step.type },
|
|
19784
|
+
details: {
|
|
19785
|
+
sourceVariable,
|
|
19786
|
+
originStepIndex: origin.index,
|
|
19787
|
+
originStepName: origin.name,
|
|
19788
|
+
responseFormat: origin.responseFormat
|
|
19789
|
+
}
|
|
19790
|
+
},
|
|
19791
|
+
buckets
|
|
19792
|
+
);
|
|
19793
|
+
}
|
|
19794
|
+
}
|
|
19795
|
+
}
|
|
19796
|
+
const outputVar = getStepOutputVariable(step);
|
|
19797
|
+
if (outputVar) {
|
|
19798
|
+
if (step.type === "prompt" && promptResponseFormatIsNonJson(config3.responseFormat)) {
|
|
19799
|
+
const responseFormat = typeof config3.responseFormat === "string" ? config3.responseFormat : "default";
|
|
19800
|
+
stringPromptOutputs.set(outputVar, { index: stepIndex, name: step.name, responseFormat });
|
|
19801
|
+
} else {
|
|
19802
|
+
stringPromptOutputs.delete(outputVar);
|
|
19803
|
+
}
|
|
19804
|
+
}
|
|
19805
|
+
}
|
|
19806
|
+
}
|
|
19807
|
+
function collectAccountScopedReferences(step, stepIndex, pendingChecks) {
|
|
19808
|
+
const stepRef = {
|
|
19809
|
+
index: stepIndex,
|
|
19810
|
+
name: step.name,
|
|
19811
|
+
type: step.type
|
|
19812
|
+
};
|
|
19813
|
+
if (!isObjectRecord(step.config)) {
|
|
19814
|
+
return;
|
|
19815
|
+
}
|
|
19816
|
+
if (step.type === "execute-agent") {
|
|
19817
|
+
const agentId = step.config.agentId;
|
|
19818
|
+
if (typeof agentId === "string" && !agentId.includes("{{")) {
|
|
19819
|
+
const path18 = `flowSteps[${stepIndex}].config.agentId`;
|
|
19820
|
+
registerAgentReference(agentId, path18, stepRef, pendingChecks);
|
|
19821
|
+
}
|
|
19822
|
+
return;
|
|
19823
|
+
}
|
|
19824
|
+
if (step.type === "tool-call") {
|
|
19825
|
+
const toolId = step.config.toolId;
|
|
19826
|
+
if (typeof toolId === "string") {
|
|
19827
|
+
const path18 = `flowSteps[${stepIndex}].config.toolId`;
|
|
19828
|
+
const named = parseNamedToolRef(toolId);
|
|
19829
|
+
if (named) {
|
|
19830
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19831
|
+
registerReference(pendingChecks.toolReferencesByName, named.name, { path: path18, step: stepRef });
|
|
19832
|
+
} else {
|
|
19833
|
+
const { customToolIds } = separateToolIds([toolId]);
|
|
19834
|
+
if (customToolIds.length > 0) {
|
|
19835
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19836
|
+
registerReference(pendingChecks.toolReferencesById, toolId, { path: path18, step: stepRef });
|
|
19837
|
+
}
|
|
19838
|
+
}
|
|
19839
|
+
}
|
|
19840
|
+
return;
|
|
19841
|
+
}
|
|
19842
|
+
if (step.type !== "prompt" && step.type !== "transform-data") {
|
|
19843
|
+
return;
|
|
19844
|
+
}
|
|
19845
|
+
const toolsConfig = step.config.tools;
|
|
19846
|
+
if (!isObjectRecord(toolsConfig)) {
|
|
19847
|
+
return;
|
|
19848
|
+
}
|
|
19849
|
+
const toolIds = toolsConfig.toolIds;
|
|
19850
|
+
if (Array.isArray(toolIds)) {
|
|
19851
|
+
for (const [toolIdIndex, toolId] of toolIds.entries()) {
|
|
19852
|
+
if (typeof toolId !== "string") {
|
|
19853
|
+
continue;
|
|
19854
|
+
}
|
|
19855
|
+
const path18 = `flowSteps[${stepIndex}].config.tools.toolIds[${toolIdIndex}]`;
|
|
19856
|
+
const named = parseNamedToolRef(toolId);
|
|
19857
|
+
if (named) {
|
|
19858
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19859
|
+
registerReference(pendingChecks.toolReferencesByName, named.name, { path: path18, step: stepRef });
|
|
19860
|
+
continue;
|
|
19861
|
+
}
|
|
19862
|
+
const { customToolIds } = separateToolIds([toolId]);
|
|
19863
|
+
if (customToolIds.length > 0) {
|
|
19864
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19865
|
+
registerReference(pendingChecks.toolReferencesById, toolId, { path: path18, step: stepRef });
|
|
19866
|
+
}
|
|
19867
|
+
}
|
|
19868
|
+
}
|
|
19869
|
+
if (step.type === "transform-data") {
|
|
19870
|
+
collectTransformDataCodeToolNameCheck(toolsConfig, stepIndex, stepRef, pendingChecks);
|
|
19871
|
+
} else {
|
|
19872
|
+
collectCodeModeToolNameCheck(toolsConfig, stepIndex, stepRef, pendingChecks);
|
|
19873
|
+
}
|
|
19874
|
+
const runtimeTools = toolsConfig.runtimeTools;
|
|
19875
|
+
if (!Array.isArray(runtimeTools)) {
|
|
19876
|
+
return;
|
|
19877
|
+
}
|
|
19878
|
+
for (const [runtimeToolIndex, runtimeTool] of runtimeTools.entries()) {
|
|
19879
|
+
if (!isObjectRecord(runtimeTool)) {
|
|
19880
|
+
continue;
|
|
19881
|
+
}
|
|
19882
|
+
const runtimeConfig = runtimeTool.config;
|
|
19883
|
+
if (!isObjectRecord(runtimeConfig)) {
|
|
19884
|
+
continue;
|
|
19885
|
+
}
|
|
19886
|
+
const basePath = `flowSteps[${stepIndex}].config.tools.runtimeTools[${runtimeToolIndex}].config`;
|
|
19887
|
+
if (runtimeTool.toolType === "flow") {
|
|
19888
|
+
const flowId = runtimeConfig.flowId;
|
|
19889
|
+
if (typeof flowId === "string") {
|
|
19890
|
+
registerFlowReference(flowId, `${basePath}.flowId`, stepRef, pendingChecks);
|
|
19891
|
+
}
|
|
19892
|
+
continue;
|
|
19893
|
+
}
|
|
19894
|
+
if (runtimeTool.toolType === "subagent") {
|
|
19895
|
+
const agentId = runtimeConfig.agentId;
|
|
19896
|
+
if (typeof agentId === "string" && !agentId.includes("{{")) {
|
|
19897
|
+
registerAgentReference(agentId, `${basePath}.agentId`, stepRef, pendingChecks);
|
|
19898
|
+
}
|
|
19899
|
+
continue;
|
|
19900
|
+
}
|
|
19901
|
+
}
|
|
19902
|
+
}
|
|
19903
|
+
function registerAgentReference(agentId, path18, stepRef, pendingChecks) {
|
|
19904
|
+
const named = parseNamedAgentRef(agentId);
|
|
19905
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19906
|
+
if (named) {
|
|
19907
|
+
registerReference(pendingChecks.agentReferencesByName, named.name, { path: path18, step: stepRef });
|
|
19908
|
+
} else {
|
|
19909
|
+
registerReference(pendingChecks.agentReferencesById, agentId, { path: path18, step: stepRef });
|
|
19910
|
+
}
|
|
19911
|
+
}
|
|
19912
|
+
function registerFlowReference(flowId, path18, stepRef, pendingChecks) {
|
|
19913
|
+
const named = parseNamedFlowRef(flowId);
|
|
19914
|
+
pendingChecks.hasAccountScopedReferences = true;
|
|
19915
|
+
if (named) {
|
|
19916
|
+
registerReference(pendingChecks.flowReferencesByName, named.name, { path: path18, step: stepRef });
|
|
19917
|
+
} else {
|
|
19918
|
+
registerReference(pendingChecks.flowReferencesById, flowId, { path: path18, step: stepRef });
|
|
19919
|
+
}
|
|
19920
|
+
}
|
|
19921
|
+
function validateSubagentConfig(value, stepTools, stepIndex, stepRef) {
|
|
19922
|
+
const basePath = `flowSteps[${stepIndex}].config.tools.subagentConfig`;
|
|
19923
|
+
if (!isObjectRecord(value)) {
|
|
19924
|
+
return {
|
|
19925
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19926
|
+
message: "subagentConfig must be an object.",
|
|
19927
|
+
path: basePath,
|
|
19928
|
+
step: stepRef
|
|
19929
|
+
};
|
|
19930
|
+
}
|
|
19931
|
+
const cfg = value;
|
|
19932
|
+
if (!Array.isArray(cfg.toolPool)) {
|
|
19933
|
+
return {
|
|
19934
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19935
|
+
message: "subagentConfig.toolPool must be an array of tool IDs (wildcards allowed).",
|
|
19936
|
+
path: `${basePath}.toolPool`,
|
|
19937
|
+
step: stepRef
|
|
19938
|
+
};
|
|
19939
|
+
}
|
|
19940
|
+
const parentToolIds = new Set(
|
|
19941
|
+
Array.isArray(stepTools.toolIds) ? stepTools.toolIds.filter((x2) => typeof x2 === "string") : []
|
|
19942
|
+
);
|
|
19943
|
+
const parentRuntimeToolNames = new Set(
|
|
19944
|
+
Array.isArray(stepTools.runtimeTools) ? stepTools.runtimeTools.map((t) => t.name).filter((n) => typeof n === "string") : []
|
|
19945
|
+
);
|
|
19946
|
+
for (const entry of cfg.toolPool) {
|
|
19947
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
19948
|
+
return {
|
|
19949
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19950
|
+
message: "subagentConfig.toolPool entries must be non-empty strings.",
|
|
19951
|
+
path: `${basePath}.toolPool`,
|
|
19952
|
+
step: stepRef
|
|
19953
|
+
};
|
|
19954
|
+
}
|
|
19955
|
+
const isWildcard2 = entry.endsWith(":*");
|
|
19956
|
+
if (isWildcard2) continue;
|
|
19957
|
+
if (!parentToolIds.has(entry) && !parentRuntimeToolNames.has(entry)) {
|
|
19958
|
+
return {
|
|
19959
|
+
code: "SUBAGENT_CONFIG_ESCALATION",
|
|
19960
|
+
message: `subagentConfig.toolPool entry "${entry}" is not granted to the parent step. Every pool entry must be a wildcard (\`foo:*\`) or appear in the parent step's toolIds or runtimeTools \u2014 otherwise the spawned subagent cannot actually call it.`,
|
|
19961
|
+
path: `${basePath}.toolPool`,
|
|
19962
|
+
step: stepRef
|
|
19963
|
+
};
|
|
19964
|
+
}
|
|
19965
|
+
}
|
|
19966
|
+
if (cfg.defaultMaxTurns !== void 0) {
|
|
19967
|
+
const n = cfg.defaultMaxTurns;
|
|
19968
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
19969
|
+
return {
|
|
19970
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19971
|
+
message: "subagentConfig.defaultMaxTurns must be a positive integer.",
|
|
19972
|
+
path: `${basePath}.defaultMaxTurns`,
|
|
19973
|
+
step: stepRef
|
|
19974
|
+
};
|
|
19975
|
+
}
|
|
19976
|
+
}
|
|
19977
|
+
if (cfg.maxTurnsLimit !== void 0) {
|
|
19978
|
+
const n = cfg.maxTurnsLimit;
|
|
19979
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
19980
|
+
return {
|
|
19981
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19982
|
+
message: "subagentConfig.maxTurnsLimit must be a positive integer.",
|
|
19983
|
+
path: `${basePath}.maxTurnsLimit`,
|
|
19984
|
+
step: stepRef
|
|
19985
|
+
};
|
|
19986
|
+
}
|
|
19987
|
+
}
|
|
19988
|
+
if (cfg.maxSpawnsPerRun !== void 0) {
|
|
19989
|
+
const n = cfg.maxSpawnsPerRun;
|
|
19990
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
19991
|
+
return {
|
|
19992
|
+
code: "SUBAGENT_CONFIG_INVALID",
|
|
19993
|
+
message: "subagentConfig.maxSpawnsPerRun must be a positive integer.",
|
|
19994
|
+
path: `${basePath}.maxSpawnsPerRun`,
|
|
19995
|
+
step: stepRef
|
|
19996
|
+
};
|
|
19997
|
+
}
|
|
19998
|
+
}
|
|
19999
|
+
return null;
|
|
20000
|
+
}
|
|
20001
|
+
function validateCodeModeConfig(value, stepTools, stepIndex, stepRef) {
|
|
20002
|
+
const basePath = `flowSteps[${stepIndex}].config.tools.codeModeConfig`;
|
|
20003
|
+
if (!isObjectRecord(value)) {
|
|
20004
|
+
return {
|
|
20005
|
+
code: "CODE_MODE_CONFIG_INVALID",
|
|
20006
|
+
message: "codeModeConfig must be an object.",
|
|
20007
|
+
path: basePath,
|
|
20008
|
+
step: stepRef
|
|
20009
|
+
};
|
|
20010
|
+
}
|
|
20011
|
+
const cfg = value;
|
|
20012
|
+
if (!Array.isArray(cfg.toolPool)) {
|
|
20013
|
+
return {
|
|
20014
|
+
code: "CODE_MODE_CONFIG_INVALID",
|
|
20015
|
+
message: "codeModeConfig.toolPool must be an array of tool IDs (wildcards allowed).",
|
|
20016
|
+
path: `${basePath}.toolPool`,
|
|
20017
|
+
step: stepRef
|
|
20018
|
+
};
|
|
20019
|
+
}
|
|
20020
|
+
const parentToolIds = new Set(
|
|
20021
|
+
Array.isArray(stepTools.toolIds) ? stepTools.toolIds.filter((x2) => typeof x2 === "string") : []
|
|
20022
|
+
);
|
|
20023
|
+
const parentRuntimeTools = Array.isArray(stepTools.runtimeTools) ? stepTools.runtimeTools : [];
|
|
20024
|
+
const parentRuntimeToolNames = new Set(
|
|
20025
|
+
parentRuntimeTools.map((t) => t.name).filter((n) => typeof n === "string")
|
|
20026
|
+
);
|
|
20027
|
+
const runtimeToolByName = new Map(
|
|
20028
|
+
parentRuntimeTools.filter((t) => typeof t.name === "string").map((t) => [t.name, t])
|
|
20029
|
+
);
|
|
20030
|
+
const selectedRuntimeToolNames = [];
|
|
20031
|
+
for (const entry of cfg.toolPool) {
|
|
20032
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
20033
|
+
return {
|
|
20034
|
+
code: "CODE_MODE_CONFIG_INVALID",
|
|
20035
|
+
message: "codeModeConfig.toolPool entries must be non-empty strings.",
|
|
20036
|
+
path: `${basePath}.toolPool`,
|
|
20037
|
+
step: stepRef
|
|
20038
|
+
};
|
|
20039
|
+
}
|
|
20040
|
+
const isWildcard2 = entry.endsWith(":*");
|
|
20041
|
+
if (isWildcard2) continue;
|
|
20042
|
+
const runtimeTool = runtimeToolByName.get(entry);
|
|
20043
|
+
if (runtimeTool) {
|
|
20044
|
+
if (runtimeTool.toolType === "local") {
|
|
20045
|
+
return {
|
|
20046
|
+
code: "CODE_MODE_CONFIG_INVALID",
|
|
20047
|
+
message: `codeModeConfig.toolPool entry "${entry}" is a local tool. Code mode cannot pause for client-side local tool callbacks.`,
|
|
20048
|
+
path: `${basePath}.toolPool`,
|
|
20049
|
+
step: stepRef
|
|
20050
|
+
};
|
|
20051
|
+
}
|
|
20052
|
+
selectedRuntimeToolNames.push({
|
|
20053
|
+
name: entry,
|
|
20054
|
+
path: `${basePath}.toolPool`
|
|
20055
|
+
});
|
|
20056
|
+
}
|
|
20057
|
+
if (!parentToolIds.has(entry) && !parentRuntimeToolNames.has(entry)) {
|
|
20058
|
+
return {
|
|
20059
|
+
code: "CODE_MODE_CONFIG_ESCALATION",
|
|
20060
|
+
message: `codeModeConfig.toolPool entry "${entry}" is not granted to the parent step. Every pool entry must be a wildcard (\`foo:*\`) or appear in the parent step's toolIds or runtimeTools \u2014 otherwise the sandbox code cannot actually call it.`,
|
|
20061
|
+
path: `${basePath}.toolPool`,
|
|
20062
|
+
step: stepRef
|
|
20063
|
+
};
|
|
20064
|
+
}
|
|
20065
|
+
}
|
|
20066
|
+
const collision = validateCodeToolNameCollisions(
|
|
20067
|
+
selectedRuntimeToolNames,
|
|
20068
|
+
stepRef,
|
|
20069
|
+
"CODE_MODE_TOOL_NAME_COLLISION"
|
|
20070
|
+
);
|
|
20071
|
+
if (collision) {
|
|
20072
|
+
return collision;
|
|
20073
|
+
}
|
|
20074
|
+
if (cfg.timeoutMs !== void 0) {
|
|
20075
|
+
const n = cfg.timeoutMs;
|
|
20076
|
+
if (typeof n !== "number" || !Number.isFinite(n) || n < 1e3 || n > 6e5) {
|
|
20077
|
+
return {
|
|
20078
|
+
code: "CODE_MODE_CONFIG_INVALID",
|
|
20079
|
+
message: "codeModeConfig.timeoutMs must be a number between 1000 and 600000.",
|
|
20080
|
+
path: `${basePath}.timeoutMs`,
|
|
20081
|
+
step: stepRef
|
|
20082
|
+
};
|
|
20083
|
+
}
|
|
20084
|
+
}
|
|
20085
|
+
return null;
|
|
20086
|
+
}
|
|
20087
|
+
function validateTransformDataCodeTools(toolsConfig, stepIndex, stepRef, buckets) {
|
|
20088
|
+
const runtimeTools = Array.isArray(toolsConfig.runtimeTools) ? toolsConfig.runtimeTools : [];
|
|
20089
|
+
const runtimeToolNames = [];
|
|
20090
|
+
for (const [runtimeToolIndex, runtimeTool] of runtimeTools.entries()) {
|
|
20091
|
+
if (!isObjectRecord(runtimeTool)) {
|
|
20092
|
+
continue;
|
|
20093
|
+
}
|
|
20094
|
+
const basePath = `flowSteps[${stepIndex}].config.tools.runtimeTools[${runtimeToolIndex}]`;
|
|
20095
|
+
const name = runtimeTool.name;
|
|
20096
|
+
if (typeof name === "string") {
|
|
20097
|
+
runtimeToolNames.push({ name, path: `${basePath}.name` });
|
|
20098
|
+
}
|
|
20099
|
+
if (runtimeTool.toolType === "local") {
|
|
20100
|
+
addIssue(
|
|
20101
|
+
"error",
|
|
20102
|
+
{
|
|
20103
|
+
code: "CODE_STEP_LOCAL_TOOL_UNSUPPORTED",
|
|
20104
|
+
message: "Transform-data code steps do not support local tools because code execution cannot pause for client-side callbacks.",
|
|
20105
|
+
path: `${basePath}.toolType`,
|
|
20106
|
+
step: stepRef
|
|
20107
|
+
},
|
|
20108
|
+
buckets
|
|
20109
|
+
);
|
|
20110
|
+
}
|
|
20111
|
+
}
|
|
20112
|
+
const collision = validateCodeToolNameCollisions(
|
|
20113
|
+
runtimeToolNames,
|
|
20114
|
+
stepRef,
|
|
20115
|
+
"CODE_STEP_TOOL_NAME_COLLISION"
|
|
20116
|
+
);
|
|
20117
|
+
if (collision) {
|
|
20118
|
+
addIssue("error", collision, buckets);
|
|
20119
|
+
}
|
|
20120
|
+
}
|
|
20121
|
+
function validateErrorHandlingTriggers(errorHandling, stepIndex, stepRef, buckets) {
|
|
20122
|
+
if (!isObjectRecord(errorHandling) || !Array.isArray(errorHandling.triggers)) {
|
|
20123
|
+
return;
|
|
20124
|
+
}
|
|
20125
|
+
for (const [triggerIndex, trigger] of errorHandling.triggers.entries()) {
|
|
20126
|
+
if (!isObjectRecord(trigger) || trigger.type !== "slow") continue;
|
|
20127
|
+
const afterMs = trigger.afterMs;
|
|
20128
|
+
if (typeof afterMs !== "number" || !Number.isFinite(afterMs) || afterMs <= 0) {
|
|
20129
|
+
addIssue(
|
|
20130
|
+
"error",
|
|
20131
|
+
{
|
|
20132
|
+
code: "SLOW_TRIGGER_INVALID_AFTER_MS",
|
|
20133
|
+
message: 'A "slow" fallback trigger requires a positive "afterMs" (the total-duration cap in milliseconds) before it can fire.',
|
|
20134
|
+
path: `flowSteps[${stepIndex}].config.errorHandling.triggers[${triggerIndex}].afterMs`,
|
|
20135
|
+
step: stepRef,
|
|
20136
|
+
details: { afterMs }
|
|
20137
|
+
},
|
|
20138
|
+
buckets
|
|
20139
|
+
);
|
|
20140
|
+
}
|
|
20141
|
+
}
|
|
20142
|
+
}
|
|
20143
|
+
function collectFlowStructureIssues(flowData, deps, buckets) {
|
|
20144
|
+
const pendingChecks = {
|
|
20145
|
+
hasAccountScopedReferences: false,
|
|
20146
|
+
toolReferencesById: /* @__PURE__ */ new Map(),
|
|
20147
|
+
toolReferencesByName: /* @__PURE__ */ new Map(),
|
|
20148
|
+
flowReferencesById: /* @__PURE__ */ new Map(),
|
|
20149
|
+
agentReferencesById: /* @__PURE__ */ new Map(),
|
|
20150
|
+
agentReferencesByName: /* @__PURE__ */ new Map(),
|
|
20151
|
+
flowReferencesByName: /* @__PURE__ */ new Map(),
|
|
20152
|
+
codeToolNameChecks: []
|
|
20153
|
+
};
|
|
20154
|
+
const orderToStepIndexes = /* @__PURE__ */ new Map();
|
|
20155
|
+
const normalizedOrders = flowData.flowSteps.map((step, index) => step.order ?? index);
|
|
20156
|
+
for (const [index, order] of normalizedOrders.entries()) {
|
|
20157
|
+
const existing = orderToStepIndexes.get(order) || [];
|
|
20158
|
+
existing.push(index);
|
|
20159
|
+
orderToStepIndexes.set(order, existing);
|
|
20160
|
+
}
|
|
20161
|
+
for (const [order, indexes] of orderToStepIndexes.entries()) {
|
|
20162
|
+
if (indexes.length <= 1) {
|
|
20163
|
+
continue;
|
|
20164
|
+
}
|
|
20165
|
+
addIssue(
|
|
20166
|
+
"warning",
|
|
20167
|
+
{
|
|
20168
|
+
code: "DUPLICATE_STEP_ORDER",
|
|
20169
|
+
message: `Multiple steps share order "${order}". Execution order may be ambiguous.`,
|
|
20170
|
+
details: { order, stepIndexes: indexes }
|
|
20171
|
+
},
|
|
20172
|
+
buckets
|
|
20173
|
+
);
|
|
20174
|
+
}
|
|
20175
|
+
const idToStepIndexes = /* @__PURE__ */ new Map();
|
|
20176
|
+
for (const [index, step] of flowData.flowSteps.entries()) {
|
|
20177
|
+
if (typeof step.id !== "string" || step.id.length === 0) continue;
|
|
20178
|
+
const existing = idToStepIndexes.get(step.id) || [];
|
|
20179
|
+
existing.push(index);
|
|
20180
|
+
idToStepIndexes.set(step.id, existing);
|
|
20181
|
+
}
|
|
20182
|
+
for (const [id, indexes] of idToStepIndexes.entries()) {
|
|
20183
|
+
if (indexes.length <= 1) continue;
|
|
20184
|
+
addIssue(
|
|
20185
|
+
"error",
|
|
20186
|
+
{
|
|
20187
|
+
code: "DUPLICATE_STEP_ID",
|
|
20188
|
+
message: `Multiple steps share id "${id}". Step ids must be unique within a flow.`,
|
|
20189
|
+
details: { id, stepIndexes: indexes }
|
|
20190
|
+
},
|
|
20191
|
+
buckets
|
|
20192
|
+
);
|
|
20193
|
+
}
|
|
20194
|
+
const enabledSteps = flowData.flowSteps.filter((step) => step.enabled !== false);
|
|
20195
|
+
if (enabledSteps.length === 0) {
|
|
20196
|
+
addIssue(
|
|
20197
|
+
"warning",
|
|
20198
|
+
{
|
|
20199
|
+
code: "NO_ENABLED_STEPS",
|
|
20200
|
+
message: "This flow has no enabled steps."
|
|
20201
|
+
},
|
|
20202
|
+
buckets
|
|
20203
|
+
);
|
|
20204
|
+
}
|
|
20205
|
+
if (!enabledSteps.some((step) => step.type === "prompt")) {
|
|
20206
|
+
addIssue(
|
|
20207
|
+
"recommendation",
|
|
20208
|
+
{
|
|
20209
|
+
code: "NO_PROMPT_STEPS",
|
|
20210
|
+
message: "No enabled prompt steps were found. Most flows require at least one prompt step."
|
|
20211
|
+
},
|
|
20212
|
+
buckets
|
|
20213
|
+
);
|
|
20214
|
+
}
|
|
20215
|
+
const conditionalStepsExceedingDepth = /* @__PURE__ */ new Set();
|
|
20216
|
+
const declaredVariables = /* @__PURE__ */ new Set();
|
|
20217
|
+
for (const [stepIndex, step] of flowData.flowSteps.entries()) {
|
|
20218
|
+
const stepRef = {
|
|
20219
|
+
index: stepIndex,
|
|
20220
|
+
name: step.name,
|
|
20221
|
+
type: step.type
|
|
20222
|
+
};
|
|
20223
|
+
if (step.type === "conditional" && conditionalNestingDepth(step.config) > MAX_CONDITIONAL_NESTING_DEPTH) {
|
|
20224
|
+
conditionalStepsExceedingDepth.add(stepIndex);
|
|
20225
|
+
addIssue(
|
|
20226
|
+
"error",
|
|
20227
|
+
{
|
|
20228
|
+
code: "CONDITIONAL_NESTING_TOO_DEEP",
|
|
20229
|
+
message: `Conditional steps may nest at most ${MAX_CONDITIONAL_NESTING_DEPTH} levels deep.`,
|
|
20230
|
+
path: `flowSteps[${stepIndex}].config`,
|
|
20231
|
+
step: stepRef
|
|
20232
|
+
},
|
|
20233
|
+
buckets
|
|
20234
|
+
);
|
|
20235
|
+
continue;
|
|
20236
|
+
}
|
|
20237
|
+
const configSchema = deps.configSchemas?.[step.type];
|
|
20238
|
+
if (configSchema) {
|
|
20239
|
+
const schemaResult = configSchema.safeParse(step.config);
|
|
20240
|
+
if (!schemaResult.success) {
|
|
20241
|
+
for (const issue2 of schemaResult.error.issues) {
|
|
20242
|
+
const issuePath = issue2.path.length > 0 ? `flowSteps[${stepIndex}].config.${formatPath(issue2.path)}` : `flowSteps[${stepIndex}].config`;
|
|
20243
|
+
addIssue("error", buildIssueFromZod(issue2, issuePath, stepRef), buckets);
|
|
20244
|
+
}
|
|
20245
|
+
}
|
|
20246
|
+
}
|
|
20247
|
+
if (isObjectRecord(step.config)) {
|
|
20248
|
+
validateErrorHandlingTriggers(step.config.errorHandling, stepIndex, stepRef, buckets);
|
|
20249
|
+
}
|
|
20250
|
+
if (isObjectRecord(step.config) && isObjectRecord(step.config.tools)) {
|
|
20251
|
+
for (const key of Object.keys(step.config.tools)) {
|
|
20252
|
+
if (KNOWN_TOOL_KEYS.has(key)) continue;
|
|
20253
|
+
const suggestion = LEGACY_TOOL_KEY_SUGGESTIONS[key];
|
|
20254
|
+
addIssue(
|
|
20255
|
+
"warning",
|
|
20256
|
+
{
|
|
20257
|
+
code: "UNKNOWN_PROMPT_TOOLS_FIELD",
|
|
20258
|
+
message: suggestion ? `Unknown field "${key}" under config.tools \u2014 did you mean "${suggestion}"? The runtime will ignore this value.` : `Unknown field "${key}" under config.tools \u2014 the runtime will ignore it. Expected keys: ${[...KNOWN_TOOL_KEYS].join(", ")}.`,
|
|
20259
|
+
path: `flowSteps[${stepIndex}].config.tools.${key}`,
|
|
20260
|
+
step: stepRef,
|
|
20261
|
+
details: suggestion ? { field: key, suggestion } : { field: key }
|
|
20262
|
+
},
|
|
20263
|
+
buckets
|
|
20264
|
+
);
|
|
20265
|
+
}
|
|
20266
|
+
if (deps.validateRuntimeTools) {
|
|
20267
|
+
const runtimeToolsValidation = deps.validateRuntimeTools(step.config.tools);
|
|
20268
|
+
if (!runtimeToolsValidation.valid) {
|
|
20269
|
+
addIssue(
|
|
20270
|
+
"error",
|
|
20271
|
+
{
|
|
20272
|
+
code: "RUNTIME_TOOLS_INVALID",
|
|
20273
|
+
message: runtimeToolsValidation.error || "Invalid runtime tools configuration",
|
|
20274
|
+
path: `flowSteps[${stepIndex}].config.tools`,
|
|
20275
|
+
step: stepRef
|
|
20276
|
+
},
|
|
20277
|
+
buckets
|
|
20278
|
+
);
|
|
20279
|
+
}
|
|
20280
|
+
}
|
|
20281
|
+
if (step.type === "transform-data") {
|
|
20282
|
+
validateTransformDataCodeTools(step.config.tools, stepIndex, stepRef, buckets);
|
|
20283
|
+
}
|
|
20284
|
+
const subagentCfg = step.config.tools.subagentConfig;
|
|
20285
|
+
if (subagentCfg !== void 0) {
|
|
20286
|
+
const issue2 = validateSubagentConfig(subagentCfg, step.config.tools, stepIndex, stepRef);
|
|
20287
|
+
if (issue2) addIssue("error", issue2, buckets);
|
|
20288
|
+
}
|
|
20289
|
+
const codeModeCfg = step.config.tools.codeModeConfig;
|
|
20290
|
+
if (codeModeCfg !== void 0) {
|
|
20291
|
+
const issue2 = validateCodeModeConfig(codeModeCfg, step.config.tools, stepIndex, stepRef);
|
|
20292
|
+
if (issue2) addIssue("error", issue2, buckets);
|
|
20293
|
+
}
|
|
20294
|
+
}
|
|
20295
|
+
if (step.type !== "prompt") {
|
|
20296
|
+
try {
|
|
20297
|
+
normalizeContextStep(
|
|
20298
|
+
{
|
|
20299
|
+
id: `step_validation_${stepIndex}`,
|
|
20300
|
+
type: step.type,
|
|
20301
|
+
name: step.name,
|
|
20302
|
+
order: step.order ?? stepIndex,
|
|
20303
|
+
enabled: step.enabled ?? true,
|
|
20304
|
+
config: step.config
|
|
20305
|
+
},
|
|
20306
|
+
{
|
|
20307
|
+
managedSendFromDomain: deps.managedSendFromDomain
|
|
20308
|
+
}
|
|
20309
|
+
);
|
|
20310
|
+
} catch (error51) {
|
|
20311
|
+
const normalizationError = error51 instanceof NormalizationError ? error51 : null;
|
|
20312
|
+
const fallbackMessage = error51 instanceof Error ? error51.message : String(error51);
|
|
20313
|
+
const fieldName = normalizationError?.fieldName;
|
|
20314
|
+
addIssue(
|
|
20315
|
+
"error",
|
|
20316
|
+
{
|
|
20317
|
+
code: "CONTEXT_STEP_INVALID",
|
|
20318
|
+
message: normalizationError?.message || fallbackMessage,
|
|
20319
|
+
path: fieldName ? `flowSteps[${stepIndex}].config.${fieldName}` : `flowSteps[${stepIndex}].config`,
|
|
20320
|
+
step: stepRef
|
|
20321
|
+
},
|
|
20322
|
+
buckets
|
|
20323
|
+
);
|
|
20324
|
+
}
|
|
20325
|
+
}
|
|
20326
|
+
if (step.type === "transform-data" && step.enabled !== false && isObjectRecord(step.config)) {
|
|
20327
|
+
const config3 = step.config;
|
|
20328
|
+
const sandboxProvider = config3.sandboxProvider || "cloudflare-worker";
|
|
20329
|
+
const resolvedProvider = sandboxProvider === "cloudflare-sandbox" ? "runtype-sandbox" : sandboxProvider;
|
|
20330
|
+
validateSandboxNetworkAccess(config3, stepIndex, stepRef, buckets);
|
|
20331
|
+
if (resolvedProvider === "runtype-sandbox" && !config3.language) {
|
|
20332
|
+
addIssue(
|
|
20333
|
+
"warning",
|
|
20334
|
+
{
|
|
20335
|
+
code: "MISSING_LANGUAGE",
|
|
20336
|
+
message: 'language is recommended when sandboxProvider is "runtype-sandbox" \u2014 defaults to "javascript" but you should specify "javascript", "typescript", or "python" explicitly',
|
|
20337
|
+
path: `flowSteps[${stepIndex}].config.language`,
|
|
20338
|
+
step: stepRef
|
|
20339
|
+
},
|
|
20340
|
+
buckets
|
|
20341
|
+
);
|
|
20342
|
+
}
|
|
20343
|
+
if (deps.validateScript && config3.inputMode !== "variable" && typeof config3.script === "string" && config3.script.trim()) {
|
|
20344
|
+
const codeResult = deps.validateScript(
|
|
20345
|
+
config3.script,
|
|
20346
|
+
{
|
|
20347
|
+
sandboxProvider,
|
|
20348
|
+
language: config3.language,
|
|
20349
|
+
availableVariables: [...declaredVariables]
|
|
20350
|
+
},
|
|
20351
|
+
{ stepIndex }
|
|
20352
|
+
);
|
|
20353
|
+
for (const issue2 of codeResult.issues) {
|
|
20354
|
+
const location = issue2.line ? ` (line ${issue2.line}, column ${issue2.column})` : "";
|
|
20355
|
+
const issueCode = issue2.code === "SYNTAX_ERROR" ? "CODE_SYNTAX_ERROR" : `CODE_${issue2.code}`;
|
|
20356
|
+
addIssue(
|
|
20357
|
+
issue2.severity,
|
|
20358
|
+
{
|
|
20359
|
+
code: issueCode,
|
|
20360
|
+
message: `${issue2.message}${location}`,
|
|
20361
|
+
path: `flowSteps[${stepIndex}].config.script`,
|
|
20362
|
+
step: stepRef,
|
|
20363
|
+
details: {
|
|
20364
|
+
language: config3.language || "javascript",
|
|
20365
|
+
sandboxProvider,
|
|
20366
|
+
...issue2.line !== void 0 ? { line: issue2.line } : {},
|
|
20367
|
+
...issue2.column !== void 0 ? { column: issue2.column } : {}
|
|
20368
|
+
}
|
|
20369
|
+
},
|
|
20370
|
+
buckets
|
|
20371
|
+
);
|
|
20372
|
+
}
|
|
20373
|
+
}
|
|
20374
|
+
}
|
|
20375
|
+
collectAccountScopedReferences(step, stepIndex, pendingChecks);
|
|
20376
|
+
if (step.enabled !== false) {
|
|
20377
|
+
const outputVar = getStepOutputVariable(step);
|
|
20378
|
+
if (outputVar) declaredVariables.add(outputVar);
|
|
20379
|
+
}
|
|
20380
|
+
}
|
|
20381
|
+
validateVariableReferences(
|
|
20382
|
+
flowData.flowSteps,
|
|
20383
|
+
buckets,
|
|
20384
|
+
conditionalStepsExceedingDepth,
|
|
20385
|
+
deps.declaredFlowInputs
|
|
20386
|
+
);
|
|
20387
|
+
validateUpsertRecordSourceShape(flowData.flowSteps, buckets);
|
|
20388
|
+
return { pendingChecks };
|
|
20389
|
+
}
|
|
20390
|
+
function validateFlowStructure(flowData, deps = {}) {
|
|
20391
|
+
const buckets = { errors: [], warnings: [], recommendations: [] };
|
|
20392
|
+
collectFlowStructureIssues(flowData, deps, buckets);
|
|
20393
|
+
const errors = sortIssues(buckets.errors);
|
|
20394
|
+
return {
|
|
20395
|
+
valid: errors.length === 0,
|
|
20396
|
+
errors,
|
|
20397
|
+
warnings: sortIssues(buckets.warnings),
|
|
20398
|
+
recommendations: sortIssues(buckets.recommendations),
|
|
20399
|
+
context: {
|
|
20400
|
+
authenticated: false,
|
|
20401
|
+
accountChecksPerformed: false,
|
|
20402
|
+
accountChecksSkipped: false
|
|
20403
|
+
}
|
|
20404
|
+
};
|
|
20405
|
+
}
|
|
20406
|
+
function parseCreateFlowValidationInput(payload) {
|
|
20407
|
+
const parsed = createFlowValidationSchema.safeParse(payload);
|
|
20408
|
+
if (parsed.success) {
|
|
20409
|
+
return {
|
|
20410
|
+
success: true,
|
|
20411
|
+
data: parsed.data
|
|
20412
|
+
};
|
|
20413
|
+
}
|
|
20414
|
+
return {
|
|
20415
|
+
success: false,
|
|
20416
|
+
errors: sortIssues(
|
|
20417
|
+
parsed.error.issues.map(
|
|
20418
|
+
(issue2) => buildIssueFromZod(issue2, formatPath(issue2.path) || "root", void 0)
|
|
20419
|
+
)
|
|
20420
|
+
)
|
|
20421
|
+
};
|
|
20422
|
+
}
|
|
17309
20423
|
var SERIALIZED_HELPERS_SOURCE = `
|
|
17310
20424
|
// Transform helper functions (from packages/shared/src/transform-helpers.ts)
|
|
17311
20425
|
const helpers = (function createHelpers() {
|
|
@@ -36737,6 +39851,7 @@ function mergeResults(...results) {
|
|
|
36737
39851
|
merged.valid = merged.errors.length === 0;
|
|
36738
39852
|
return merged;
|
|
36739
39853
|
}
|
|
39854
|
+
var NAMESPACE_VARIABLE_CODES = /* @__PURE__ */ new Set(["UNDECLARED_VARIABLE_REFERENCE", "UNKNOWN_VARIABLE_NAMESPACE"]);
|
|
36740
39855
|
function validateFlowDefinition(flow, capIndex, context) {
|
|
36741
39856
|
const result = emptyResult();
|
|
36742
39857
|
const base = `capabilities[${capIndex}].flow`;
|
|
@@ -36797,8 +39912,25 @@ function validateFlowDefinition(flow, capIndex, context) {
|
|
|
36797
39912
|
}
|
|
36798
39913
|
}
|
|
36799
39914
|
}
|
|
39915
|
+
appendNamespaceVariableIssues(flow, base, result);
|
|
36800
39916
|
return finalize2(result);
|
|
36801
39917
|
}
|
|
39918
|
+
function reprefixCorePath(corePath, base) {
|
|
39919
|
+
if (!corePath) return `${base}.steps`;
|
|
39920
|
+
return corePath.replace(/^flowSteps\[/, `${base}.steps[`);
|
|
39921
|
+
}
|
|
39922
|
+
function appendNamespaceVariableIssues(flow, base, result) {
|
|
39923
|
+
const parsed = parseCreateFlowValidationInput({ name: flow.name, flowSteps: flow.steps });
|
|
39924
|
+
if (!parsed.success) return;
|
|
39925
|
+
const coreResult = validateFlowStructure(parsed.data);
|
|
39926
|
+
const push = (issue2, severity) => {
|
|
39927
|
+
if (!NAMESPACE_VARIABLE_CODES.has(issue2.code)) return;
|
|
39928
|
+
const bucket = severity === "error" ? result.errors : result.warnings;
|
|
39929
|
+
bucket.push(createIssue(severity, issue2.code, issue2.message, reprefixCorePath(issue2.path, base)));
|
|
39930
|
+
};
|
|
39931
|
+
for (const issue2 of coreResult.errors) push(issue2, "error");
|
|
39932
|
+
for (const issue2 of coreResult.warnings) push(issue2, "warning");
|
|
39933
|
+
}
|
|
36802
39934
|
function finalize2(r) {
|
|
36803
39935
|
r.valid = r.errors.length === 0;
|
|
36804
39936
|
return r;
|
|
@@ -37426,8 +40558,10 @@ var fullProductObjectTemplateSchema = external_exports.object({
|
|
|
37426
40558
|
});
|
|
37427
40559
|
}
|
|
37428
40560
|
});
|
|
37429
|
-
var FLOW_PREFIX = "flow
|
|
37430
|
-
var SECRET_PREFIX =
|
|
40561
|
+
var FLOW_PREFIX = Object.values(RUNTIME_PREFIXES).find((spec) => spec.namespace === "flow").prefix;
|
|
40562
|
+
var SECRET_PREFIX = Object.values(RUNTIME_PREFIXES).find(
|
|
40563
|
+
(spec) => spec.namespace === "secret"
|
|
40564
|
+
).prefix;
|
|
37431
40565
|
function collectStringLeafPaths(value, path18 = []) {
|
|
37432
40566
|
if (typeof value === "string") {
|
|
37433
40567
|
return [{ path: path18, value }];
|
|
@@ -37458,12 +40592,16 @@ function extractTemplateReferences(value) {
|
|
|
37458
40592
|
const inner = value.slice(start + 2, end);
|
|
37459
40593
|
const separatorIndex = inner.indexOf("|");
|
|
37460
40594
|
const key = (separatorIndex === -1 ? inner : inner.slice(0, separatorIndex)).trim();
|
|
37461
|
-
if (key.length > 0
|
|
37462
|
-
|
|
37463
|
-
|
|
37464
|
-
|
|
37465
|
-
|
|
37466
|
-
|
|
40595
|
+
if (key.length > 0) {
|
|
40596
|
+
const classification = classifyVariableReference(key);
|
|
40597
|
+
const ownedByRuntimeOrEngine = classification.namespace === "secret" || classification.namespace === "flow" || classification.namespace === "system";
|
|
40598
|
+
if (!ownedByRuntimeOrEngine) {
|
|
40599
|
+
references.push({
|
|
40600
|
+
key,
|
|
40601
|
+
defaultValue: separatorIndex === -1 ? void 0 : inner.slice(separatorIndex + 1).trim(),
|
|
40602
|
+
raw
|
|
40603
|
+
});
|
|
40604
|
+
}
|
|
37467
40605
|
}
|
|
37468
40606
|
cursor = end + 2;
|
|
37469
40607
|
}
|
|
@@ -44280,26 +47418,26 @@ async function getCurrentAccountId() {
|
|
|
44280
47418
|
|
|
44281
47419
|
// src/lib/quick-start-api.ts
|
|
44282
47420
|
import { RuntypeApiError as RuntypeApiError2 } from "@runtypelabs/sdk";
|
|
44283
|
-
function
|
|
47421
|
+
function isObjectRecord2(value) {
|
|
44284
47422
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
44285
47423
|
}
|
|
44286
47424
|
function isQuickStartValidationResponse(value) {
|
|
44287
|
-
if (!
|
|
47425
|
+
if (!isObjectRecord2(value) || typeof value.valid !== "boolean") {
|
|
44288
47426
|
return false;
|
|
44289
47427
|
}
|
|
44290
47428
|
if (value.valid === false) {
|
|
44291
47429
|
return typeof value.error === "string" && typeof value.code === "string";
|
|
44292
47430
|
}
|
|
44293
|
-
return typeof value.templateId === "string" &&
|
|
47431
|
+
return typeof value.templateId === "string" && isObjectRecord2(value.agentCard);
|
|
44294
47432
|
}
|
|
44295
47433
|
function isQuickStartCreateResponse(value) {
|
|
44296
|
-
if (!
|
|
47434
|
+
if (!isObjectRecord2(value) || typeof value.success !== "boolean") {
|
|
44297
47435
|
return false;
|
|
44298
47436
|
}
|
|
44299
47437
|
if (value.success === false) {
|
|
44300
47438
|
return typeof value.error === "string" && typeof value.code === "string";
|
|
44301
47439
|
}
|
|
44302
|
-
return
|
|
47440
|
+
return isObjectRecord2(value.product) && Array.isArray(value.capabilities) && typeof value.redirectUrl === "string";
|
|
44303
47441
|
}
|
|
44304
47442
|
function getApiErrorData(error51) {
|
|
44305
47443
|
return error51 instanceof RuntypeApiError2 ? error51.data : void 0;
|
|
@@ -56323,6 +59461,11 @@ function buildResumeHistoryWarning(state) {
|
|
|
56323
59461
|
function canUseMarathonStartupShell(options) {
|
|
56324
59462
|
return process.stdin.isTTY === true && process.stdout.isTTY === true && !options.json;
|
|
56325
59463
|
}
|
|
59464
|
+
function formatBytes(bytes) {
|
|
59465
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
59466
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
59467
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
59468
|
+
}
|
|
56326
59469
|
function normalizeStartupModelOptionValue(value) {
|
|
56327
59470
|
const trimmed = value?.trim().toLowerCase().replace(/^model\//, "") ?? "";
|
|
56328
59471
|
if (!trimmed) return "";
|
|
@@ -56903,6 +60046,18 @@ async function taskAction(agent, options) {
|
|
|
56903
60046
|
const sandboxWorkflowSelection = playbookWorkflow ? void 0 : resolveSandboxWorkflowSelection(baseMessage, parsedSandbox, resumeState);
|
|
56904
60047
|
parsedSandbox = sandboxWorkflowSelection?.sandboxProvider ?? parsedSandbox;
|
|
56905
60048
|
const resolvedWorkflow = playbookWorkflow ?? sandboxWorkflowSelection?.workflow;
|
|
60049
|
+
if (!resolvedWorkflow && !playbookWorkflow && !resumeState && !isDeployCapableSandbox(parsedSandbox) && (isGameIntent(baseMessage) || isDeployIntent(baseMessage))) {
|
|
60050
|
+
console.log(
|
|
60051
|
+
chalk23.yellow(
|
|
60052
|
+
"Hint: this goal looks like a build-and-deploy task, but no deploy-capable sandbox is enabled."
|
|
60053
|
+
)
|
|
60054
|
+
);
|
|
60055
|
+
console.log(
|
|
60056
|
+
chalk23.gray(
|
|
60057
|
+
" Re-run with --sandbox daytona to build and deploy to a live preview URL (enables the deploy_sandbox tool)."
|
|
60058
|
+
)
|
|
60059
|
+
);
|
|
60060
|
+
}
|
|
56906
60061
|
const DEFAULT_MILESTONE_NAMES = ["research", "planning", "execution"];
|
|
56907
60062
|
const EXTERNAL_MILESTONE_NAMES = ["research", "report"];
|
|
56908
60063
|
const detectedVariant = resumeState?.workflowVariant ?? defaultWorkflow.classifyVariant?.(baseMessage);
|
|
@@ -57238,6 +60393,11 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
57238
60393
|
let accumulatedCost = 0;
|
|
57239
60394
|
let accumulatedTokens = { input: 0, output: 0 };
|
|
57240
60395
|
let accumulatedToolCalls = 0;
|
|
60396
|
+
let indexedChunks = 0;
|
|
60397
|
+
let indexedBytes = 0;
|
|
60398
|
+
let indexingFailures = 0;
|
|
60399
|
+
let indexingFailureNoticed = false;
|
|
60400
|
+
const indexingRequests = [];
|
|
57241
60401
|
let lastResult = null;
|
|
57242
60402
|
let lastSessionMessages = [];
|
|
57243
60403
|
let undeliveredSteering = [];
|
|
@@ -57409,12 +60569,35 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
57409
60569
|
});
|
|
57410
60570
|
if (chunks.length > 0) {
|
|
57411
60571
|
const sessionIdx = currentSessionOffset + state.sessionCount - 1;
|
|
57412
|
-
|
|
60572
|
+
const payloadBytes = Buffer.byteLength(JSON.stringify(chunks), "utf-8");
|
|
60573
|
+
indexedChunks += chunks.length;
|
|
60574
|
+
indexedBytes += payloadBytes;
|
|
60575
|
+
const NOTICE_BYTES = 512 * 1024;
|
|
60576
|
+
if (payloadBytes >= NOTICE_BYTES) {
|
|
60577
|
+
reportContextNotice({
|
|
60578
|
+
kind: "session_indexed",
|
|
60579
|
+
message: `Session ${sessionIdx} indexed ${chunks.length.toLocaleString()} chunks (${formatBytes(payloadBytes)}) for semantic search.`,
|
|
60580
|
+
sessionIndex: sessionIdx,
|
|
60581
|
+
chunkCount: chunks.length,
|
|
60582
|
+
payloadBytes
|
|
60583
|
+
});
|
|
60584
|
+
}
|
|
60585
|
+
const indexingRequest = client.post("/session-context/index", {
|
|
57413
60586
|
taskName,
|
|
57414
60587
|
sessionIndex: sessionIdx,
|
|
57415
60588
|
chunks
|
|
57416
|
-
}).catch(() => {
|
|
60589
|
+
}).catch((error51) => {
|
|
60590
|
+
indexingFailures++;
|
|
60591
|
+
if (!indexingFailureNoticed) {
|
|
60592
|
+
indexingFailureNoticed = true;
|
|
60593
|
+
reportContextNotice({
|
|
60594
|
+
kind: "indexing_failed",
|
|
60595
|
+
message: `Session-search indexing failed; recall may be incomplete (${error51 instanceof Error ? error51.message : String(error51)}). Pass --no-session-search to disable indexing.`,
|
|
60596
|
+
sessionIndex: sessionIdx
|
|
60597
|
+
});
|
|
60598
|
+
}
|
|
57417
60599
|
});
|
|
60600
|
+
indexingRequests.push(indexingRequest);
|
|
57418
60601
|
}
|
|
57419
60602
|
}
|
|
57420
60603
|
}
|
|
@@ -57728,11 +60911,26 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
57728
60911
|
saveState(filePath, finalState, { stripSnapshotEvents: !!eventLogWriter });
|
|
57729
60912
|
await waitForUiExit?.();
|
|
57730
60913
|
exitAltScreen();
|
|
60914
|
+
if (indexingRequests.length > 0) {
|
|
60915
|
+
const INDEXING_SETTLE_GRACE_MS = 5e3;
|
|
60916
|
+
await Promise.race([
|
|
60917
|
+
Promise.allSettled(indexingRequests),
|
|
60918
|
+
new Promise((resolve11) => {
|
|
60919
|
+
const timer = setTimeout(resolve11, INDEXING_SETTLE_GRACE_MS);
|
|
60920
|
+
timer.unref?.();
|
|
60921
|
+
})
|
|
60922
|
+
]);
|
|
60923
|
+
}
|
|
57731
60924
|
console.log();
|
|
57732
60925
|
const statusColor = result.status === "complete" ? chalk23.green : result.status === "budget_exceeded" || result.status === "error" ? chalk23.red : chalk23.yellow;
|
|
57733
60926
|
console.log(`Status: ${statusColor(result.status)}`);
|
|
57734
60927
|
console.log(`Sessions: ${finalState.sessionCount}`);
|
|
57735
60928
|
console.log(`Total cost: ${chalk23.yellow(`$${finalState.totalCost.toFixed(4)}`)}`);
|
|
60929
|
+
if (indexedChunks > 0 || indexingFailures > 0) {
|
|
60930
|
+
const indexedLine = `${indexedChunks.toLocaleString()} chunks (${formatBytes(indexedBytes)})`;
|
|
60931
|
+
const failureSuffix = indexingFailures > 0 ? chalk23.red(` \u2014 ${indexingFailures} indexing failure${indexingFailures === 1 ? "" : "s"}`) : "";
|
|
60932
|
+
console.log(`Indexed: ${chalk23.dim(indexedLine)}${failureSuffix}`);
|
|
60933
|
+
}
|
|
57736
60934
|
console.log(`State: ${chalk23.gray(filePath)}`);
|
|
57737
60935
|
if (typeof finalState.lastError === "string" && finalState.lastError.trim()) {
|
|
57738
60936
|
console.log(`Last error: ${chalk23.red(finalState.lastError)}`);
|
|
@@ -57888,7 +61086,20 @@ ${details}`);
|
|
|
57888
61086
|
}
|
|
57889
61087
|
return resolved;
|
|
57890
61088
|
}
|
|
57891
|
-
function
|
|
61089
|
+
function isDeployCapableSandbox(provider) {
|
|
61090
|
+
return provider === "daytona" || provider === "runtype-sandbox";
|
|
61091
|
+
}
|
|
61092
|
+
function isGameIntent(message) {
|
|
61093
|
+
const lower = message.toLowerCase();
|
|
61094
|
+
return /\b(game|gameplay|playable|racing|platformer|shooter|puzzle|arcade)\b/.test(lower) || /\b(three\.?js|webgl|phaser|babylon\.?js|pixi\.?js)\b/.test(lower);
|
|
61095
|
+
}
|
|
61096
|
+
function isDeployIntent(message) {
|
|
61097
|
+
const lower = message.toLowerCase();
|
|
61098
|
+
return /\b(deploy|deployed|deployment|publish|published|host|hosted|hosting|serve|served)\b/.test(
|
|
61099
|
+
lower
|
|
61100
|
+
) || /\b(web ?app|web ?site|landing page|preview url|live url|public url)\b/.test(lower) || /\b(publicly|share with friends)\b/.test(lower);
|
|
61101
|
+
}
|
|
61102
|
+
function detectDeployWorkflow(message, sandboxProvider, resumeState) {
|
|
57892
61103
|
if (resumeState?.workflowVariant === "game") return gameWorkflow;
|
|
57893
61104
|
if (resumeState?.workflowPhase === "design" || resumeState?.workflowPhase === "build" || resumeState?.workflowPhase === "verify") {
|
|
57894
61105
|
return gameWorkflow;
|
|
@@ -57897,10 +61108,14 @@ function detectDeployWorkflow(_message, _sandboxProvider, resumeState) {
|
|
|
57897
61108
|
if (resumeState?.workflowPhase === "scaffold" || resumeState?.workflowPhase === "deploy") {
|
|
57898
61109
|
return deployWorkflow;
|
|
57899
61110
|
}
|
|
61111
|
+
if (isDeployCapableSandbox(sandboxProvider)) {
|
|
61112
|
+
if (isGameIntent(message)) return gameWorkflow;
|
|
61113
|
+
if (isDeployIntent(message)) return deployWorkflow;
|
|
61114
|
+
}
|
|
57900
61115
|
return void 0;
|
|
57901
61116
|
}
|
|
57902
61117
|
function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState) {
|
|
57903
|
-
if (sandboxProvider && sandboxProvider
|
|
61118
|
+
if (sandboxProvider && !isDeployCapableSandbox(sandboxProvider)) {
|
|
57904
61119
|
return {
|
|
57905
61120
|
workflow: void 0,
|
|
57906
61121
|
sandboxProvider
|
|
@@ -60283,8 +63498,8 @@ import { execFileSync } from "child_process";
|
|
|
60283
63498
|
// src/lib/persona-init.ts
|
|
60284
63499
|
init_credential_store();
|
|
60285
63500
|
|
|
60286
|
-
// ../../node_modules/.pnpm/@runtypelabs+persona@3.34.
|
|
60287
|
-
var S = "3.34.
|
|
63501
|
+
// ../../node_modules/.pnpm/@runtypelabs+persona@3.34.1/node_modules/@runtypelabs/persona/dist/codegen.js
|
|
63502
|
+
var S = "3.34.1";
|
|
60288
63503
|
var c = S;
|
|
60289
63504
|
function u(e) {
|
|
60290
63505
|
if (e !== void 0) return typeof e == "string" ? e : Array.isArray(e) ? `[${e.map((r) => r.toString()).join(", ")}]` : e.toString();
|