@vaudience/aigentflow-flow-validator 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PARITY.md +23 -0
- package/dist/cli.js +106 -0
- package/dist/index.cjs +105 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/PARITY.md
CHANGED
|
@@ -6,6 +6,29 @@ discipline for keeping the two in sync.
|
|
|
6
6
|
|
|
7
7
|
**Tracks AIgentFlow flow schema: `v2.831.0`** (`SPEC_VERSION` in [`src/spec/aigentflow-spec.json`](./src/spec/aigentflow-spec.json)), which adds the rule `unknown_function_operation` and a clearer `unknown_executor_scheme` message (package 0.23.0, below). Earlier: the rule `flow_data_key_reserved` (package 0.22.0). Earlier: the `here` executor scheme, the `strict_templates` flow key and the rule `template_default_piped` (package 0.21.0). Earlier: the warning `compliance_residency_unenforced` (package 0.20.0). `orchestrator.region` / `orchestrator.enforce_region` (package 0.19.0). Earlier: the AigentChat executor was removed (package 0.18.0). Earlier additions: the `examples:` block (package 0.17.0), `server_owned_query_key` (package 0.15.1) from the AIgentFlow release after v2.790.0, `credential_endpoint_unpaired` (package 0.15.2) from AIgentFlow v2.793.0 and the release after it, and `display_name_too_long` (package 0.15.3) from AIgentFlow v2.802.0.
|
|
8
8
|
|
|
9
|
+
> package 0.25.0 — **the `atlas://` executor scheme and seven rules**. `atlas` becomes a known
|
|
10
|
+
> scheme (no `unknown_executor_scheme` warning). The URL form is `atlas://<provider>/<resource>`:
|
|
11
|
+
> provider `agent` has the single resource `run`, provider `capability` takes a capability reference
|
|
12
|
+
> as its resource. Seven new **errors**, all with the step as `field` (a loop sub-step reports its
|
|
13
|
+
> sub-step path and the composite `parent.child` step id):
|
|
14
|
+
> `atlas_operation_unknown` (any other provider, or `agent` with a resource other than `run`);
|
|
15
|
+
> `atlas_agent_missing` (an agent run whose `query.agent` is absent, empty or not a string);
|
|
16
|
+
> `atlas_agent_not_literal` (`query.agent` contains `{{`: the agent is always written out, never
|
|
17
|
+
> computed from input); `atlas_capabilities_not_literal` (a string entry of `query.capabilities`
|
|
18
|
+
> contains `{{`); `atlas_prompt_missing` and `atlas_prompt_both` (an agent run takes exactly one of
|
|
19
|
+
> `query.prompt` and `query.prompt_template`; an empty string counts as absent);
|
|
20
|
+
> `atlas_capability_ref_invalid` (the reference fails `^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$`).
|
|
21
|
+
> Templates in `prompt`, in `inputs` values and in a capability's `args` are fine. A templated
|
|
22
|
+
> executor is skipped, an unparsable URL stays `invalid_executor_url`'s, and the scheme match is
|
|
23
|
+
> exact (`ATLAS://` is a known scheme but gets none of these rules). The shape check runs first, so
|
|
24
|
+
> a reference containing a character outside letters, digits, `_`, `-` and `/` (for example a dot
|
|
25
|
+
> or colon) is reported as `invalid_executor_url` and never reaches the reference pattern.
|
|
26
|
+
> `specVersion` is unchanged (`2.831.0`). Module: `validators/executors.ts`; spec block
|
|
27
|
+
> `atlasExecutor`. Gates: thirteen `invalid-atlas-*` / `valid-atlas-*` fixtures (the valid ones
|
|
28
|
+
> forbid every atlas code and `unknown_executor_scheme`), shared byte for byte with the Go port, and
|
|
29
|
+
> `test/v0250-atlas-executor.test.ts`. On the 227 bundled example flows both ports report no new
|
|
30
|
+
> findings.
|
|
31
|
+
|
|
9
32
|
> package 0.24.0 — **`potential_infinite_loop` fires only on a cycle with no way out**, in step
|
|
10
33
|
> with the reference. It used to fire on every cycle reachable from the start step, so a deliberate
|
|
11
34
|
> ask-again loop (a step that routes back until a condition sends it onward) carried a warning that
|
package/dist/cli.js
CHANGED
|
@@ -463,6 +463,7 @@ var aigentflow_spec_default = {
|
|
|
463
463
|
"ai",
|
|
464
464
|
"aiv",
|
|
465
465
|
"async",
|
|
466
|
+
"atlas",
|
|
466
467
|
"browser",
|
|
467
468
|
"chart",
|
|
468
469
|
"db",
|
|
@@ -1006,6 +1007,49 @@ var aigentflow_spec_default = {
|
|
|
1006
1007
|
"utils/parse-date"
|
|
1007
1008
|
]
|
|
1008
1009
|
},
|
|
1010
|
+
atlasExecutor: {
|
|
1011
|
+
$comment: "atlas://<provider>/<resource>: calls into the Atlas platform. Providers are agent (the one resource is run) and capability (the resource is a capability reference). All findings are ERRORS, field = the step (loop sub-steps use the composite step id and the sub-step path). Templated executors, unparsable URLs and other schemes are skipped. A literal agent and literal capabilities keep a step from being steered by data: query.agent and every string in query.capabilities may not contain templateActionOpen, while prompt, inputs and capability args may. A message format takes the quoted step id first.",
|
|
1012
|
+
scheme: "atlas",
|
|
1013
|
+
providerAgent: "agent",
|
|
1014
|
+
providerCapability: "capability",
|
|
1015
|
+
agentResource: "run",
|
|
1016
|
+
capabilityRefPattern: "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
|
|
1017
|
+
operationUnknown: {
|
|
1018
|
+
code: "atlas_operation_unknown",
|
|
1019
|
+
messageFormat: "step %s uses %s, which is not an Atlas operation. The providers are agent (resource run) and capability (resource: a capability reference).",
|
|
1020
|
+
suggestion: "Use atlas://agent/run or atlas://capability/<capability-ref>."
|
|
1021
|
+
},
|
|
1022
|
+
agentMissing: {
|
|
1023
|
+
code: "atlas_agent_missing",
|
|
1024
|
+
messageFormat: "step %s runs an Atlas agent but query.agent is missing or empty.",
|
|
1025
|
+
suggestion: "Set query.agent to the agent to run, written out as a literal such as @acme/reporter."
|
|
1026
|
+
},
|
|
1027
|
+
agentNotLiteral: {
|
|
1028
|
+
code: "atlas_agent_not_literal",
|
|
1029
|
+
messageFormat: "step %s computes query.agent from a template. The agent must be a fixed literal, never derived from input.",
|
|
1030
|
+
suggestion: "Write the agent out as a literal such as @acme/reporter. Data may go into the prompt or the inputs instead."
|
|
1031
|
+
},
|
|
1032
|
+
capabilitiesNotLiteral: {
|
|
1033
|
+
code: "atlas_capabilities_not_literal",
|
|
1034
|
+
messageFormat: "step %s computes an entry of query.capabilities from a template. Capabilities must be fixed literals, never derived from input.",
|
|
1035
|
+
suggestion: "Write each capability out as a literal. Data may go into the prompt or the inputs instead."
|
|
1036
|
+
},
|
|
1037
|
+
promptMissing: {
|
|
1038
|
+
code: "atlas_prompt_missing",
|
|
1039
|
+
messageFormat: "step %s runs an Atlas agent with neither query.prompt nor query.prompt_template.",
|
|
1040
|
+
suggestion: "Set exactly one of query.prompt or query.prompt_template."
|
|
1041
|
+
},
|
|
1042
|
+
promptBoth: {
|
|
1043
|
+
code: "atlas_prompt_both",
|
|
1044
|
+
messageFormat: "step %s sets both query.prompt and query.prompt_template.",
|
|
1045
|
+
suggestion: "Keep exactly one of query.prompt or query.prompt_template."
|
|
1046
|
+
},
|
|
1047
|
+
capabilityRefInvalid: {
|
|
1048
|
+
code: "atlas_capability_ref_invalid",
|
|
1049
|
+
messageFormat: "step %s uses atlas://capability/%s, which is not a valid capability reference.",
|
|
1050
|
+
suggestion: "A capability reference starts with a letter or digit and continues with letters, digits and _ . : - up to 128 characters in all."
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1009
1053
|
flowDataReservedKeys: {
|
|
1010
1054
|
$comment: "flow_data_key_reserved (ERROR, no loop demotion): a key of the top-level data: map that names engine state. data: is seeded into the mission's .data namespace, where the engine keeps its own bookkeeping, so a flow declaring such a key would forge it. Matching is exact and case-sensitive. A key is reserved when it is one of exact (each with its reason), or starts with one of prefixes (checked in order, first wins; each with its reason). The finding's field is fieldFormat with the key; the message is messageFormat with the key (JSON-quoted, as Go's %q) then the reason; the suggestion is verbatim. Findings are sorted by key. Reference: FlowDataKeyReservation, validateFlowDataKeysAreNotReserved (aigentflow#247 review).",
|
|
1011
1055
|
code: "flow_data_key_reserved",
|
|
@@ -2129,6 +2173,21 @@ var FUNCTION_OPERATIONS = {
|
|
|
2129
2173
|
operations: new Set(aigentflow_spec_default.functionOperations.operations),
|
|
2130
2174
|
sorted: aigentflow_spec_default.functionOperations.operations
|
|
2131
2175
|
};
|
|
2176
|
+
var atlas = aigentflow_spec_default.atlasExecutor;
|
|
2177
|
+
var ATLAS_EXECUTOR = {
|
|
2178
|
+
scheme: atlas.scheme,
|
|
2179
|
+
providerAgent: atlas.providerAgent,
|
|
2180
|
+
providerCapability: atlas.providerCapability,
|
|
2181
|
+
agentResource: atlas.agentResource,
|
|
2182
|
+
capabilityRefPattern: new RegExp(atlas.capabilityRefPattern),
|
|
2183
|
+
operationUnknown: atlas.operationUnknown,
|
|
2184
|
+
agentMissing: atlas.agentMissing,
|
|
2185
|
+
agentNotLiteral: atlas.agentNotLiteral,
|
|
2186
|
+
capabilitiesNotLiteral: atlas.capabilitiesNotLiteral,
|
|
2187
|
+
promptMissing: atlas.promptMissing,
|
|
2188
|
+
promptBoth: atlas.promptBoth,
|
|
2189
|
+
capabilityRefInvalid: atlas.capabilityRefInvalid
|
|
2190
|
+
};
|
|
2132
2191
|
|
|
2133
2192
|
// src/validators/executors.ts
|
|
2134
2193
|
var SCHEME_SEPARATOR = "://";
|
|
@@ -2192,6 +2251,51 @@ function checkExecutor(executor, field, stepID, issues) {
|
|
|
2192
2251
|
}
|
|
2193
2252
|
checkFunctionOperation(executor, field, stepID, templated, issues);
|
|
2194
2253
|
}
|
|
2254
|
+
function checkAtlasStep(executor, query, stepField, stepID, issues) {
|
|
2255
|
+
if (executor.includes(TEMPLATE_ACTION_OPEN)) return;
|
|
2256
|
+
const m = EXECUTOR_URL_PATTERN.exec(executor);
|
|
2257
|
+
if (m === null || m[1] !== ATLAS_EXECUTOR.scheme) return;
|
|
2258
|
+
const provider = m[2];
|
|
2259
|
+
const resource = m[3];
|
|
2260
|
+
const quoted = JSON.stringify(stepID);
|
|
2261
|
+
const report = (rule, ...args) => {
|
|
2262
|
+
let message = rule.messageFormat.replace("%s", () => quoted);
|
|
2263
|
+
for (const a of args) message = message.replace("%s", () => a);
|
|
2264
|
+
issues.error({
|
|
2265
|
+
field: stepField,
|
|
2266
|
+
message,
|
|
2267
|
+
code: rule.code,
|
|
2268
|
+
stepId: stepID,
|
|
2269
|
+
suggestion: rule.suggestion
|
|
2270
|
+
});
|
|
2271
|
+
};
|
|
2272
|
+
const q2 = isRecord(query) ? query : {};
|
|
2273
|
+
if (provider === ATLAS_EXECUTOR.providerCapability) {
|
|
2274
|
+
if (!ATLAS_EXECUTOR.capabilityRefPattern.test(resource)) {
|
|
2275
|
+
report(ATLAS_EXECUTOR.capabilityRefInvalid, resource);
|
|
2276
|
+
}
|
|
2277
|
+
} else if (provider === ATLAS_EXECUTOR.providerAgent && resource === ATLAS_EXECUTOR.agentResource) {
|
|
2278
|
+
const agent = q2.agent;
|
|
2279
|
+
if (typeof agent !== "string" || agent === "") {
|
|
2280
|
+
report(ATLAS_EXECUTOR.agentMissing);
|
|
2281
|
+
} else if (agent.includes(TEMPLATE_ACTION_OPEN)) {
|
|
2282
|
+
report(ATLAS_EXECUTOR.agentNotLiteral);
|
|
2283
|
+
}
|
|
2284
|
+
const prompt = q2.prompt;
|
|
2285
|
+
const promptTemplate = q2.prompt_template;
|
|
2286
|
+
const hasPrompt = prompt !== void 0 && prompt !== null && prompt !== "";
|
|
2287
|
+
const hasTemplate = promptTemplate !== void 0 && promptTemplate !== null && promptTemplate !== "";
|
|
2288
|
+
if (!hasPrompt && !hasTemplate) report(ATLAS_EXECUTOR.promptMissing);
|
|
2289
|
+
else if (hasPrompt && hasTemplate) report(ATLAS_EXECUTOR.promptBoth);
|
|
2290
|
+
} else {
|
|
2291
|
+
report(ATLAS_EXECUTOR.operationUnknown, executor);
|
|
2292
|
+
return;
|
|
2293
|
+
}
|
|
2294
|
+
const caps = q2.capabilities;
|
|
2295
|
+
if (Array.isArray(caps) && caps.some((c) => typeof c === "string" && c.includes(TEMPLATE_ACTION_OPEN))) {
|
|
2296
|
+
report(ATLAS_EXECUTOR.capabilitiesNotLiteral);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2195
2299
|
function checkFunctionOperation(executor, field, stepID, templated, issues) {
|
|
2196
2300
|
if (templated) return;
|
|
2197
2301
|
const m = EXECUTOR_URL_PATTERN.exec(executor);
|
|
@@ -2216,6 +2320,7 @@ function validateExecutors(flow, issues) {
|
|
|
2216
2320
|
const executor = issues.stringOf(step, "executor", `steps.${stepID}`);
|
|
2217
2321
|
if (executor !== null && executor !== "") {
|
|
2218
2322
|
checkExecutor(executor, `steps.${stepID}.executor`, stepID, issues);
|
|
2323
|
+
checkAtlasStep(executor, step.query, `steps.${stepID}`, stepID, issues);
|
|
2219
2324
|
}
|
|
2220
2325
|
const loop = step.loop;
|
|
2221
2326
|
if (isRecord(loop) && Array.isArray(loop.steps)) {
|
|
@@ -2232,6 +2337,7 @@ function validateExecutors(flow, issues) {
|
|
|
2232
2337
|
`${stepID}.${subID}`,
|
|
2233
2338
|
issues
|
|
2234
2339
|
);
|
|
2340
|
+
checkAtlasStep(subExecutor, subStep.query, subPath, `${stepID}.${subID}`, issues);
|
|
2235
2341
|
}
|
|
2236
2342
|
});
|
|
2237
2343
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -459,6 +459,7 @@ var aigentflow_spec_default = {
|
|
|
459
459
|
"ai",
|
|
460
460
|
"aiv",
|
|
461
461
|
"async",
|
|
462
|
+
"atlas",
|
|
462
463
|
"browser",
|
|
463
464
|
"chart",
|
|
464
465
|
"db",
|
|
@@ -988,6 +989,48 @@ var aigentflow_spec_default = {
|
|
|
988
989
|
"utils/parse-date"
|
|
989
990
|
]
|
|
990
991
|
},
|
|
992
|
+
atlasExecutor: {
|
|
993
|
+
scheme: "atlas",
|
|
994
|
+
providerAgent: "agent",
|
|
995
|
+
providerCapability: "capability",
|
|
996
|
+
agentResource: "run",
|
|
997
|
+
capabilityRefPattern: "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
|
|
998
|
+
operationUnknown: {
|
|
999
|
+
code: "atlas_operation_unknown",
|
|
1000
|
+
messageFormat: "step %s uses %s, which is not an Atlas operation. The providers are agent (resource run) and capability (resource: a capability reference).",
|
|
1001
|
+
suggestion: "Use atlas://agent/run or atlas://capability/<capability-ref>."
|
|
1002
|
+
},
|
|
1003
|
+
agentMissing: {
|
|
1004
|
+
code: "atlas_agent_missing",
|
|
1005
|
+
messageFormat: "step %s runs an Atlas agent but query.agent is missing or empty.",
|
|
1006
|
+
suggestion: "Set query.agent to the agent to run, written out as a literal such as @acme/reporter."
|
|
1007
|
+
},
|
|
1008
|
+
agentNotLiteral: {
|
|
1009
|
+
code: "atlas_agent_not_literal",
|
|
1010
|
+
messageFormat: "step %s computes query.agent from a template. The agent must be a fixed literal, never derived from input.",
|
|
1011
|
+
suggestion: "Write the agent out as a literal such as @acme/reporter. Data may go into the prompt or the inputs instead."
|
|
1012
|
+
},
|
|
1013
|
+
capabilitiesNotLiteral: {
|
|
1014
|
+
code: "atlas_capabilities_not_literal",
|
|
1015
|
+
messageFormat: "step %s computes an entry of query.capabilities from a template. Capabilities must be fixed literals, never derived from input.",
|
|
1016
|
+
suggestion: "Write each capability out as a literal. Data may go into the prompt or the inputs instead."
|
|
1017
|
+
},
|
|
1018
|
+
promptMissing: {
|
|
1019
|
+
code: "atlas_prompt_missing",
|
|
1020
|
+
messageFormat: "step %s runs an Atlas agent with neither query.prompt nor query.prompt_template.",
|
|
1021
|
+
suggestion: "Set exactly one of query.prompt or query.prompt_template."
|
|
1022
|
+
},
|
|
1023
|
+
promptBoth: {
|
|
1024
|
+
code: "atlas_prompt_both",
|
|
1025
|
+
messageFormat: "step %s sets both query.prompt and query.prompt_template.",
|
|
1026
|
+
suggestion: "Keep exactly one of query.prompt or query.prompt_template."
|
|
1027
|
+
},
|
|
1028
|
+
capabilityRefInvalid: {
|
|
1029
|
+
code: "atlas_capability_ref_invalid",
|
|
1030
|
+
messageFormat: "step %s uses atlas://capability/%s, which is not a valid capability reference.",
|
|
1031
|
+
suggestion: "A capability reference starts with a letter or digit and continues with letters, digits and _ . : - up to 128 characters in all."
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
991
1034
|
flowDataReservedKeys: {
|
|
992
1035
|
code: "flow_data_key_reserved",
|
|
993
1036
|
fieldFormat: "data.%s",
|
|
@@ -2030,6 +2073,21 @@ var FUNCTION_OPERATIONS = {
|
|
|
2030
2073
|
operations: new Set(aigentflow_spec_default.functionOperations.operations),
|
|
2031
2074
|
sorted: aigentflow_spec_default.functionOperations.operations
|
|
2032
2075
|
};
|
|
2076
|
+
var atlas = aigentflow_spec_default.atlasExecutor;
|
|
2077
|
+
var ATLAS_EXECUTOR = {
|
|
2078
|
+
scheme: atlas.scheme,
|
|
2079
|
+
providerAgent: atlas.providerAgent,
|
|
2080
|
+
providerCapability: atlas.providerCapability,
|
|
2081
|
+
agentResource: atlas.agentResource,
|
|
2082
|
+
capabilityRefPattern: new RegExp(atlas.capabilityRefPattern),
|
|
2083
|
+
operationUnknown: atlas.operationUnknown,
|
|
2084
|
+
agentMissing: atlas.agentMissing,
|
|
2085
|
+
agentNotLiteral: atlas.agentNotLiteral,
|
|
2086
|
+
capabilitiesNotLiteral: atlas.capabilitiesNotLiteral,
|
|
2087
|
+
promptMissing: atlas.promptMissing,
|
|
2088
|
+
promptBoth: atlas.promptBoth,
|
|
2089
|
+
capabilityRefInvalid: atlas.capabilityRefInvalid
|
|
2090
|
+
};
|
|
2033
2091
|
|
|
2034
2092
|
// src/validators/executors.ts
|
|
2035
2093
|
var SCHEME_SEPARATOR = "://";
|
|
@@ -2093,6 +2151,51 @@ function checkExecutor(executor, field, stepID, issues) {
|
|
|
2093
2151
|
}
|
|
2094
2152
|
checkFunctionOperation(executor, field, stepID, templated, issues);
|
|
2095
2153
|
}
|
|
2154
|
+
function checkAtlasStep(executor, query, stepField, stepID, issues) {
|
|
2155
|
+
if (executor.includes(TEMPLATE_ACTION_OPEN)) return;
|
|
2156
|
+
const m = EXECUTOR_URL_PATTERN.exec(executor);
|
|
2157
|
+
if (m === null || m[1] !== ATLAS_EXECUTOR.scheme) return;
|
|
2158
|
+
const provider = m[2];
|
|
2159
|
+
const resource = m[3];
|
|
2160
|
+
const quoted = JSON.stringify(stepID);
|
|
2161
|
+
const report = (rule, ...args) => {
|
|
2162
|
+
let message = rule.messageFormat.replace("%s", () => quoted);
|
|
2163
|
+
for (const a of args) message = message.replace("%s", () => a);
|
|
2164
|
+
issues.error({
|
|
2165
|
+
field: stepField,
|
|
2166
|
+
message,
|
|
2167
|
+
code: rule.code,
|
|
2168
|
+
stepId: stepID,
|
|
2169
|
+
suggestion: rule.suggestion
|
|
2170
|
+
});
|
|
2171
|
+
};
|
|
2172
|
+
const q2 = isRecord(query) ? query : {};
|
|
2173
|
+
if (provider === ATLAS_EXECUTOR.providerCapability) {
|
|
2174
|
+
if (!ATLAS_EXECUTOR.capabilityRefPattern.test(resource)) {
|
|
2175
|
+
report(ATLAS_EXECUTOR.capabilityRefInvalid, resource);
|
|
2176
|
+
}
|
|
2177
|
+
} else if (provider === ATLAS_EXECUTOR.providerAgent && resource === ATLAS_EXECUTOR.agentResource) {
|
|
2178
|
+
const agent = q2.agent;
|
|
2179
|
+
if (typeof agent !== "string" || agent === "") {
|
|
2180
|
+
report(ATLAS_EXECUTOR.agentMissing);
|
|
2181
|
+
} else if (agent.includes(TEMPLATE_ACTION_OPEN)) {
|
|
2182
|
+
report(ATLAS_EXECUTOR.agentNotLiteral);
|
|
2183
|
+
}
|
|
2184
|
+
const prompt = q2.prompt;
|
|
2185
|
+
const promptTemplate = q2.prompt_template;
|
|
2186
|
+
const hasPrompt = prompt !== void 0 && prompt !== null && prompt !== "";
|
|
2187
|
+
const hasTemplate = promptTemplate !== void 0 && promptTemplate !== null && promptTemplate !== "";
|
|
2188
|
+
if (!hasPrompt && !hasTemplate) report(ATLAS_EXECUTOR.promptMissing);
|
|
2189
|
+
else if (hasPrompt && hasTemplate) report(ATLAS_EXECUTOR.promptBoth);
|
|
2190
|
+
} else {
|
|
2191
|
+
report(ATLAS_EXECUTOR.operationUnknown, executor);
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
const caps = q2.capabilities;
|
|
2195
|
+
if (Array.isArray(caps) && caps.some((c) => typeof c === "string" && c.includes(TEMPLATE_ACTION_OPEN))) {
|
|
2196
|
+
report(ATLAS_EXECUTOR.capabilitiesNotLiteral);
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2096
2199
|
function checkFunctionOperation(executor, field, stepID, templated, issues) {
|
|
2097
2200
|
if (templated) return;
|
|
2098
2201
|
const m = EXECUTOR_URL_PATTERN.exec(executor);
|
|
@@ -2117,6 +2220,7 @@ function validateExecutors(flow, issues) {
|
|
|
2117
2220
|
const executor = issues.stringOf(step, "executor", `steps.${stepID}`);
|
|
2118
2221
|
if (executor !== null && executor !== "") {
|
|
2119
2222
|
checkExecutor(executor, `steps.${stepID}.executor`, stepID, issues);
|
|
2223
|
+
checkAtlasStep(executor, step.query, `steps.${stepID}`, stepID, issues);
|
|
2120
2224
|
}
|
|
2121
2225
|
const loop = step.loop;
|
|
2122
2226
|
if (isRecord(loop) && Array.isArray(loop.steps)) {
|
|
@@ -2133,6 +2237,7 @@ function validateExecutors(flow, issues) {
|
|
|
2133
2237
|
`${stepID}.${subID}`,
|
|
2134
2238
|
issues
|
|
2135
2239
|
);
|
|
2240
|
+
checkAtlasStep(subExecutor, subStep.query, subPath, `${stepID}.${subID}`, issues);
|
|
2136
2241
|
}
|
|
2137
2242
|
});
|
|
2138
2243
|
}
|