@vaudience/aigentflow-flow-validator 0.21.0 → 0.22.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 +28 -1
- package/README.md +2 -1
- package/dist/cli.js +70 -4
- package/dist/index.cjs +69 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +69 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/PARITY.md
CHANGED
|
@@ -4,7 +4,33 @@ This document maps every rule in this JavaScript validator back to the AIgentFlo
|
|
|
4
4
|
Go reference implementation, records the intentional divergences, and defines the
|
|
5
5
|
discipline for keeping the two in sync.
|
|
6
6
|
|
|
7
|
-
**Tracks AIgentFlow flow schema: `v2.
|
|
7
|
+
**Tracks AIgentFlow flow schema: `v2.828.0`** (`SPEC_VERSION` in [`src/spec/aigentflow-spec.json`](./src/spec/aigentflow-spec.json)), which adds the rule `flow_data_key_reserved` (package 0.22.0, below). 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
|
+
|
|
9
|
+
> package 0.22.0 — **`flow_data_key_reserved`**, in step with the reference (AIgentFlow
|
|
10
|
+
> v2.828.0; `specVersion` 2.828.0). One new **error**: a key of the top-level `data:` map
|
|
11
|
+
> may not name engine state. `data:` is seeded into the mission's `.data` namespace, which
|
|
12
|
+
> is also where the engine keeps its own bookkeeping, so a flow declaring such a key would
|
|
13
|
+
> pre-seed or forge it (a taint list, the current flow, the mission's organization).
|
|
14
|
+
>
|
|
15
|
+
> | Rule (reference) | Code | Severity | Module |
|
|
16
|
+
> | -------------------------------------------------------------- | ------------------------ | -------- | --------------------------------------------------------- |
|
|
17
|
+
> | `FlowDataKeyReservation`, `validateFlowDataKeysAreNotReserved` | `flow_data_key_reserved` | error | `validators/flowDataKeys.ts`, spec `flowDataReservedKeys` |
|
|
18
|
+
>
|
|
19
|
+
> - **Reserved** (exact, case-sensitive; spec `flowDataReservedKeys`): `memory`,
|
|
20
|
+
> `orchestrator`, `campaign`, `voiceagent`, `org_id`, `current_flow`, `modified_flow`,
|
|
21
|
+
> `modification_history`, `modification_pending`, `modification_requests`,
|
|
22
|
+
> `bottleneck_state`; or a key starting with `_`, `.`, `memory.`, `orchestrator.`,
|
|
23
|
+
> `campaign.` or `voiceagent.`. Each carries the reference's reason. A key that merely
|
|
24
|
+
> contains a reserved word (`memory_notes`, `orgid`, `my_memory`) or differs in case is legal.
|
|
25
|
+
> - **Finding.** Field `data.<key>`, one per key, sorted by key; the message is the
|
|
26
|
+
> reference's `data: key "<key>" is reserved: <reason>. It would write into the engine's
|
|
27
|
+
own state, so it is not seeded.` and the suggestion its text (spec keys `messageFormat`,
|
|
28
|
+
> `suggestion`). There is no loop-body twin, so no demotion.
|
|
29
|
+
> - **Divergence from the reference's run door.** The reference tolerates this code when a
|
|
30
|
+
> stored flow is _run_ (the key is skipped, the flow still runs) and refuses it at save.
|
|
31
|
+
> This validator answers "would this save", so it is an error here, as for every other
|
|
32
|
+
> save-door rule. Key order is JavaScript's UTF-16 code-unit order, Go's is byte order;
|
|
33
|
+
> they differ only for keys with characters outside the Basic Multilingual Plane.
|
|
8
34
|
|
|
9
35
|
> package 0.21.0 — **`here://`, `strict_templates` and `template_default_piped`**, in step
|
|
10
36
|
> with the reference (AIgentFlow v2.827.0; `specVersion` 2.827.0). Three changes.
|
|
@@ -1084,6 +1110,7 @@ Comparison contract: **error `code` + `valid` verdict**, not message wording. Th
|
|
|
1084
1110
|
| `tool_discovery` vocabulary, mock scenario `delay`, empty `output:` entry | `validateToolDiscoveryVocabulary`, `validateMockScenarioDelays`, `validateOutputParameters` (parser.go) | `validators/saveDoor.ts` | `validate.test.ts`, `conformance.test.ts` |
|
|
1085
1111
|
| `executor_config` `${NAME}` references outside the key's scope (`executor_config_env_scope`) | `ValidateExecutorConfigEnvScopes` (parser.go) | `validators/executorConfigEnv.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
|
|
1086
1112
|
| A step or loop sub-step `query:` declaring a server-owned key (`server_owned_query_key`) | `validateNoServerOwnedStepQueryKeys` (validation.go), `IsServerOwnedParamKey` | `validators/serverOwnedQueryKeys.ts` | `v0151-save-door.test.ts`, `conformance.test.ts` |
|
|
1113
|
+
| A top-level `data:` key naming engine state (`flow_data_key_reserved`) | `FlowDataKeyReservation`, `validateFlowDataKeysAreNotReserved` (validation.flowdata.go) | `validators/flowDataKeys.ts` | `v0220-flow-data-keys.test.ts`, `conformance.test.ts` |
|
|
1087
1114
|
| An endpoint a server-supplied credential will never be sent to (`credential_endpoint_unpaired`, warning) | `validateCredentialEndpointPairing`, `validateFamilyCredentialEndpointPairing` (validation.go) | `validators/credentialEndpoint.ts`, `validators/goUrl.ts` | `v0152-credential-endpoint.test.ts`, `conformance.test.ts` |
|
|
1088
1115
|
| The `examples:` block: 58 codes, one walker (ids, inputs, references, expectations, checkpoints, variants) | the examples walker (`ValidateExamples`) | `validators/examples.ts`, `validators/goUrl.ts` | `examples.test.ts`, `conformance.test.ts` |
|
|
1089
1116
|
| Orchestrator `.exons` frontmatter: spec, provider, `requirements.resources`, `tools.allow` withholds | `validateOrchestrator` (parser.go), `validateOrchestratorToolAllowWithholds` | `validators/exons.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
|
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ Low-level: parse YAML into `{ flow?, parseErrors, parseWarnings }` without valid
|
|
|
116
116
|
|
|
117
117
|
### `SPEC_VERSION: string`
|
|
118
118
|
|
|
119
|
-
The AIgentFlow flow-schema version this build tracks (e.g. `"2.
|
|
119
|
+
The AIgentFlow flow-schema version this build tracks (e.g. `"2.828.0"`).
|
|
120
120
|
|
|
121
121
|
### Options
|
|
122
122
|
|
|
@@ -174,6 +174,7 @@ interface ValidationIssue {
|
|
|
174
174
|
- **Orchestrator `.exons` frontmatter** — the document must open with a closed `---` frontmatter spec (`orchestrator_exons_parse_failed`) that sets `execution.provider` (`orchestrator_exons_no_provider`) and declares no `requirements.resources` (`exons_resources_unhonoured`); a tool that `orchestrator.tools` and the definition's `tools.allow` disagree about is never offered (`orchestrator_tool_withheld`, warning). The document body is not parsed: that needs the `.exons` engine (see PARITY.md).
|
|
175
175
|
- **`executor_config` environment references** — a `${NAME}` value may name only the variables of the provider or protocol it is written under (`executor_config_env_scope`).
|
|
176
176
|
- **Server-owned query keys** — a step's or loop sub-step's `query:` may not declare `aiv_api_key`, `aiv_base_url` or `aiv_delegation`, which only the server sets (`server_owned_query_key`).
|
|
177
|
+
- **Reserved `data:` keys** — a key of the top-level `data:` map may not name engine state: `memory`, `orchestrator`, `campaign`, `voiceagent`, `org_id`, `current_flow`, the `modif*`/`bottleneck_state` bookkeeping names, a key starting with `_` or `.`, or one under `memory.`, `orchestrator.`, `campaign.`, `voiceagent.` (`flow_data_key_reserved`).
|
|
177
178
|
- **Credential endpoints** — an endpoint a server-supplied credential will never be sent to (warning, `credential_endpoint_unpaired`): an `ai://` `<provider>_base_url` or a literal `executor_config.<provider>.base_url` with no key of the flow's own, a family secret that is a server `${AIGENTFLOW_…}` variable beside a literal non-default endpoint.
|
|
178
179
|
- **Credential bindings** — `stored/{provider}/{name}` format, `inject_as`, `credential`/`credentials` mutual exclusion.
|
|
179
180
|
- **Expression functions** — exactly one of `package`/`function`.
|
package/dist/cli.js
CHANGED
|
@@ -455,7 +455,7 @@ function validateBasicStructure(flow, issues) {
|
|
|
455
455
|
// src/spec/aigentflow-spec.json
|
|
456
456
|
var aigentflow_spec_default = {
|
|
457
457
|
$comment: "Vendored enum surface mirrored from the AIgentFlow Go reference implementation. Regenerate / review on every flow-YAML schema change. See PARITY.md. Values here are public protocol/type names only.",
|
|
458
|
-
specVersion: "2.
|
|
458
|
+
specVersion: "2.828.0",
|
|
459
459
|
inputSchemaVersion: 1,
|
|
460
460
|
executorSchemes: [
|
|
461
461
|
"a2a",
|
|
@@ -965,6 +965,34 @@ var aigentflow_spec_default = {
|
|
|
965
965
|
stepFieldFormat: "steps.%s.query.%s",
|
|
966
966
|
loopStepFieldFormat: "steps.%s.loop.steps.%s.query.%s"
|
|
967
967
|
},
|
|
968
|
+
flowDataReservedKeys: {
|
|
969
|
+
$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).",
|
|
970
|
+
code: "flow_data_key_reserved",
|
|
971
|
+
fieldFormat: "data.%s",
|
|
972
|
+
messageFormat: "data: key %s is reserved: %s. It would write into the engine's own state, so it is not seeded.",
|
|
973
|
+
suggestion: "Rename the key (no leading `_` or `.`, and not one of the engine namespaces memory., orchestrator., campaign., voiceagent.).",
|
|
974
|
+
exact: {
|
|
975
|
+
org_id: "the mission's organization, set by the engine for Thalamus/Engram calls",
|
|
976
|
+
memory: "the memory scope namespace",
|
|
977
|
+
orchestrator: "the orchestrator's state namespace",
|
|
978
|
+
campaign: "the campaign's state namespace",
|
|
979
|
+
voiceagent: "the voice agent's state namespace",
|
|
980
|
+
current_flow: "engine bookkeeping (the current flow definition)",
|
|
981
|
+
modified_flow: "engine bookkeeping (dynamic flow modification)",
|
|
982
|
+
modification_history: "engine bookkeeping (dynamic flow modification)",
|
|
983
|
+
modification_pending: "engine bookkeeping (dynamic flow modification)",
|
|
984
|
+
modification_requests: "engine bookkeeping (dynamic flow modification)",
|
|
985
|
+
bottleneck_state: "engine bookkeeping (bottleneck analysis)"
|
|
986
|
+
},
|
|
987
|
+
prefixes: [
|
|
988
|
+
{ prefix: "_", reason: "keys starting with `_` are engine bookkeeping (current flow, loop and for_each context, taint lists such as `__untrusted_*`)" },
|
|
989
|
+
{ prefix: ".", reason: "keys starting with `.` are engine step-response slots" },
|
|
990
|
+
{ prefix: "memory.", reason: "the `memory.` namespace belongs to the engine" },
|
|
991
|
+
{ prefix: "orchestrator.", reason: "the `orchestrator.` namespace belongs to the orchestrator" },
|
|
992
|
+
{ prefix: "campaign.", reason: "the `campaign.` namespace belongs to the campaign engine" },
|
|
993
|
+
{ prefix: "voiceagent.", reason: "the `voiceagent.` namespace belongs to the voice agent" }
|
|
994
|
+
]
|
|
995
|
+
},
|
|
968
996
|
credentialEndpointPairing: {
|
|
969
997
|
$comment: "credential_endpoint_unpaired (WARNING, never an error): the one statically certain shape of AIgentFlow's run-time credential/endpoint pairing refusal. ai: an ai://<provider>/... step (top-level or loop sub-step) whose query holds a non-empty string <provider>+providerBaseUrlParamSuffix while neither its query (genericKeyParam or <provider>+providerKeyParamSuffix, non-empty strings) nor executor_config.<provider>.api_key (a literal, not an env reference) supplies a key; and executor_config.<provider>.base_url for a provider in executorConfigProviders when it is a literal, the block has no literal api_key, and it is not the case that at least one step uses the provider and every such step brings its own query key. keylessProviders are exempt from both. families: a step whose executor resolves (the key protocol+familyKeySeparator+driver, else protocol) to a row. implicitServerCredential rows are never judged. A row warns when its secret (the first non-empty string secretParam in the query, else per configKey in order: executor_config api_key when configApiKeyParam is a secretParam, else the first non-empty string secretParam under extra) is exactly an env reference to a serverEnv name on a row with expandsServerEnvReferences, and its endpoint (the first non-empty string endpointParam in the query, else per configKey: base_url when configBaseUrlParam is an endpointParam, else the first non-empty string endpointParam under extra) is a literal: no templateActionOpen, not an env reference, and not of the same origin as a defaultEndpoint (lower-cased scheme://host:port, defaultPorts filled). serverEnv is the reference's per-family server-variable set, evaluated. Field formats are the reference's. Reference: validateCredentialEndpointPairing (DC-FORGE-231) and validateFamilyCredentialEndpointPairing (DC-FORGE-233).",
|
|
970
998
|
stepFieldFormat: "steps.%s.query.%s",
|
|
@@ -1979,6 +2007,14 @@ var SERVER_OWNED_QUERY_KEYS = {
|
|
|
1979
2007
|
stepFieldFormat: aigentflow_spec_default.serverOwnedQueryKeys.stepFieldFormat,
|
|
1980
2008
|
loopStepFieldFormat: aigentflow_spec_default.serverOwnedQueryKeys.loopStepFieldFormat
|
|
1981
2009
|
};
|
|
2010
|
+
var FLOW_DATA_RESERVED_KEYS = {
|
|
2011
|
+
code: aigentflow_spec_default.flowDataReservedKeys.code,
|
|
2012
|
+
fieldFormat: aigentflow_spec_default.flowDataReservedKeys.fieldFormat,
|
|
2013
|
+
messageFormat: aigentflow_spec_default.flowDataReservedKeys.messageFormat,
|
|
2014
|
+
suggestion: aigentflow_spec_default.flowDataReservedKeys.suggestion,
|
|
2015
|
+
exact: aigentflow_spec_default.flowDataReservedKeys.exact,
|
|
2016
|
+
prefixes: aigentflow_spec_default.flowDataReservedKeys.prefixes
|
|
2017
|
+
};
|
|
1982
2018
|
var CREDENTIAL_ENDPOINT_PAIRING = {
|
|
1983
2019
|
stepFieldFormat: aigentflow_spec_default.credentialEndpointPairing.stepFieldFormat,
|
|
1984
2020
|
loopStepFieldFormat: aigentflow_spec_default.credentialEndpointPairing.loopStepFieldFormat,
|
|
@@ -3901,16 +3937,16 @@ function skipSpaces(src, idx) {
|
|
|
3901
3937
|
}
|
|
3902
3938
|
return i;
|
|
3903
3939
|
}
|
|
3904
|
-
function scanString(src, start,
|
|
3940
|
+
function scanString(src, start, quote2) {
|
|
3905
3941
|
let i = start + 1;
|
|
3906
|
-
const raw =
|
|
3942
|
+
const raw = quote2 === "`";
|
|
3907
3943
|
while (i < src.length) {
|
|
3908
3944
|
const c = src[i];
|
|
3909
3945
|
if (!raw && c === "\\") {
|
|
3910
3946
|
i += 2;
|
|
3911
3947
|
continue;
|
|
3912
3948
|
}
|
|
3913
|
-
if (c ===
|
|
3949
|
+
if (c === quote2) return i;
|
|
3914
3950
|
i += 1;
|
|
3915
3951
|
}
|
|
3916
3952
|
return -1;
|
|
@@ -4513,6 +4549,35 @@ function validateRetiredKeys(flow, issues) {
|
|
|
4513
4549
|
}
|
|
4514
4550
|
}
|
|
4515
4551
|
|
|
4552
|
+
// src/validators/flowDataKeys.ts
|
|
4553
|
+
var KEY_DATA = "data";
|
|
4554
|
+
function quote(key) {
|
|
4555
|
+
return JSON.stringify(key);
|
|
4556
|
+
}
|
|
4557
|
+
function flowDataKeyReservation(key) {
|
|
4558
|
+
if (Object.prototype.hasOwnProperty.call(FLOW_DATA_RESERVED_KEYS.exact, key)) {
|
|
4559
|
+
return FLOW_DATA_RESERVED_KEYS.exact[key];
|
|
4560
|
+
}
|
|
4561
|
+
for (const p of FLOW_DATA_RESERVED_KEYS.prefixes) {
|
|
4562
|
+
if (key.startsWith(p.prefix)) return p.reason;
|
|
4563
|
+
}
|
|
4564
|
+
return void 0;
|
|
4565
|
+
}
|
|
4566
|
+
function validateFlowDataKeys(flow, issues) {
|
|
4567
|
+
const data = flow[KEY_DATA];
|
|
4568
|
+
if (!isRecord(data)) return;
|
|
4569
|
+
for (const key of Object.keys(data).sort()) {
|
|
4570
|
+
const reason = flowDataKeyReservation(key);
|
|
4571
|
+
if (reason === void 0) continue;
|
|
4572
|
+
issues.error({
|
|
4573
|
+
field: FLOW_DATA_RESERVED_KEYS.fieldFormat.replace("%s", () => key),
|
|
4574
|
+
message: FLOW_DATA_RESERVED_KEYS.messageFormat.replace("%s", () => quote(key)).replace("%s", () => reason),
|
|
4575
|
+
code: FLOW_DATA_RESERVED_KEYS.code,
|
|
4576
|
+
suggestion: FLOW_DATA_RESERVED_KEYS.suggestion
|
|
4577
|
+
});
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
|
|
4516
4581
|
// src/validators/saveDoor.ts
|
|
4517
4582
|
var TOOL_DISCOVERY_MODES = /* @__PURE__ */ new Set(["eager", "lazy", "off"]);
|
|
4518
4583
|
var TEMPLATE_ACTION_OPEN2 = "{{";
|
|
@@ -6977,6 +7042,7 @@ function validateParsed(flow, opts, sources) {
|
|
|
6977
7042
|
validateSaveDoorExtras(f, issues);
|
|
6978
7043
|
validateExecutorConfigEnvScopes(f, issues);
|
|
6979
7044
|
validateServerOwnedQueryKeys(f, issues);
|
|
7045
|
+
validateFlowDataKeys(f, issues);
|
|
6980
7046
|
validateCredentialEndpointPairing(f, issues);
|
|
6981
7047
|
validateExamples(f, issues);
|
|
6982
7048
|
validateOrchestratorExons(f, issues);
|
package/dist/index.cjs
CHANGED
|
@@ -451,7 +451,7 @@ function validateBasicStructure(flow, issues) {
|
|
|
451
451
|
|
|
452
452
|
// src/spec/aigentflow-spec.json
|
|
453
453
|
var aigentflow_spec_default = {
|
|
454
|
-
specVersion: "2.
|
|
454
|
+
specVersion: "2.828.0",
|
|
455
455
|
inputSchemaVersion: 1,
|
|
456
456
|
executorSchemes: [
|
|
457
457
|
"a2a",
|
|
@@ -948,6 +948,33 @@ var aigentflow_spec_default = {
|
|
|
948
948
|
stepFieldFormat: "steps.%s.query.%s",
|
|
949
949
|
loopStepFieldFormat: "steps.%s.loop.steps.%s.query.%s"
|
|
950
950
|
},
|
|
951
|
+
flowDataReservedKeys: {
|
|
952
|
+
code: "flow_data_key_reserved",
|
|
953
|
+
fieldFormat: "data.%s",
|
|
954
|
+
messageFormat: "data: key %s is reserved: %s. It would write into the engine's own state, so it is not seeded.",
|
|
955
|
+
suggestion: "Rename the key (no leading `_` or `.`, and not one of the engine namespaces memory., orchestrator., campaign., voiceagent.).",
|
|
956
|
+
exact: {
|
|
957
|
+
org_id: "the mission's organization, set by the engine for Thalamus/Engram calls",
|
|
958
|
+
memory: "the memory scope namespace",
|
|
959
|
+
orchestrator: "the orchestrator's state namespace",
|
|
960
|
+
campaign: "the campaign's state namespace",
|
|
961
|
+
voiceagent: "the voice agent's state namespace",
|
|
962
|
+
current_flow: "engine bookkeeping (the current flow definition)",
|
|
963
|
+
modified_flow: "engine bookkeeping (dynamic flow modification)",
|
|
964
|
+
modification_history: "engine bookkeeping (dynamic flow modification)",
|
|
965
|
+
modification_pending: "engine bookkeeping (dynamic flow modification)",
|
|
966
|
+
modification_requests: "engine bookkeeping (dynamic flow modification)",
|
|
967
|
+
bottleneck_state: "engine bookkeeping (bottleneck analysis)"
|
|
968
|
+
},
|
|
969
|
+
prefixes: [
|
|
970
|
+
{ prefix: "_", reason: "keys starting with `_` are engine bookkeeping (current flow, loop and for_each context, taint lists such as `__untrusted_*`)" },
|
|
971
|
+
{ prefix: ".", reason: "keys starting with `.` are engine step-response slots" },
|
|
972
|
+
{ prefix: "memory.", reason: "the `memory.` namespace belongs to the engine" },
|
|
973
|
+
{ prefix: "orchestrator.", reason: "the `orchestrator.` namespace belongs to the orchestrator" },
|
|
974
|
+
{ prefix: "campaign.", reason: "the `campaign.` namespace belongs to the campaign engine" },
|
|
975
|
+
{ prefix: "voiceagent.", reason: "the `voiceagent.` namespace belongs to the voice agent" }
|
|
976
|
+
]
|
|
977
|
+
},
|
|
951
978
|
credentialEndpointPairing: {
|
|
952
979
|
stepFieldFormat: "steps.%s.query.%s",
|
|
953
980
|
loopStepFieldFormat: "steps.%s.loop.steps.%s.query.%s",
|
|
@@ -1885,6 +1912,14 @@ var SERVER_OWNED_QUERY_KEYS = {
|
|
|
1885
1912
|
stepFieldFormat: aigentflow_spec_default.serverOwnedQueryKeys.stepFieldFormat,
|
|
1886
1913
|
loopStepFieldFormat: aigentflow_spec_default.serverOwnedQueryKeys.loopStepFieldFormat
|
|
1887
1914
|
};
|
|
1915
|
+
var FLOW_DATA_RESERVED_KEYS = {
|
|
1916
|
+
code: aigentflow_spec_default.flowDataReservedKeys.code,
|
|
1917
|
+
fieldFormat: aigentflow_spec_default.flowDataReservedKeys.fieldFormat,
|
|
1918
|
+
messageFormat: aigentflow_spec_default.flowDataReservedKeys.messageFormat,
|
|
1919
|
+
suggestion: aigentflow_spec_default.flowDataReservedKeys.suggestion,
|
|
1920
|
+
exact: aigentflow_spec_default.flowDataReservedKeys.exact,
|
|
1921
|
+
prefixes: aigentflow_spec_default.flowDataReservedKeys.prefixes
|
|
1922
|
+
};
|
|
1888
1923
|
var CREDENTIAL_ENDPOINT_PAIRING = {
|
|
1889
1924
|
stepFieldFormat: aigentflow_spec_default.credentialEndpointPairing.stepFieldFormat,
|
|
1890
1925
|
loopStepFieldFormat: aigentflow_spec_default.credentialEndpointPairing.loopStepFieldFormat,
|
|
@@ -3804,16 +3839,16 @@ function skipSpaces(src, idx) {
|
|
|
3804
3839
|
}
|
|
3805
3840
|
return i;
|
|
3806
3841
|
}
|
|
3807
|
-
function scanString(src, start,
|
|
3842
|
+
function scanString(src, start, quote2) {
|
|
3808
3843
|
let i = start + 1;
|
|
3809
|
-
const raw =
|
|
3844
|
+
const raw = quote2 === "`";
|
|
3810
3845
|
while (i < src.length) {
|
|
3811
3846
|
const c = src[i];
|
|
3812
3847
|
if (!raw && c === "\\") {
|
|
3813
3848
|
i += 2;
|
|
3814
3849
|
continue;
|
|
3815
3850
|
}
|
|
3816
|
-
if (c ===
|
|
3851
|
+
if (c === quote2) return i;
|
|
3817
3852
|
i += 1;
|
|
3818
3853
|
}
|
|
3819
3854
|
return -1;
|
|
@@ -4416,6 +4451,35 @@ function validateRetiredKeys(flow, issues) {
|
|
|
4416
4451
|
}
|
|
4417
4452
|
}
|
|
4418
4453
|
|
|
4454
|
+
// src/validators/flowDataKeys.ts
|
|
4455
|
+
var KEY_DATA = "data";
|
|
4456
|
+
function quote(key) {
|
|
4457
|
+
return JSON.stringify(key);
|
|
4458
|
+
}
|
|
4459
|
+
function flowDataKeyReservation(key) {
|
|
4460
|
+
if (Object.prototype.hasOwnProperty.call(FLOW_DATA_RESERVED_KEYS.exact, key)) {
|
|
4461
|
+
return FLOW_DATA_RESERVED_KEYS.exact[key];
|
|
4462
|
+
}
|
|
4463
|
+
for (const p of FLOW_DATA_RESERVED_KEYS.prefixes) {
|
|
4464
|
+
if (key.startsWith(p.prefix)) return p.reason;
|
|
4465
|
+
}
|
|
4466
|
+
return void 0;
|
|
4467
|
+
}
|
|
4468
|
+
function validateFlowDataKeys(flow, issues) {
|
|
4469
|
+
const data = flow[KEY_DATA];
|
|
4470
|
+
if (!isRecord(data)) return;
|
|
4471
|
+
for (const key of Object.keys(data).sort()) {
|
|
4472
|
+
const reason = flowDataKeyReservation(key);
|
|
4473
|
+
if (reason === void 0) continue;
|
|
4474
|
+
issues.error({
|
|
4475
|
+
field: FLOW_DATA_RESERVED_KEYS.fieldFormat.replace("%s", () => key),
|
|
4476
|
+
message: FLOW_DATA_RESERVED_KEYS.messageFormat.replace("%s", () => quote(key)).replace("%s", () => reason),
|
|
4477
|
+
code: FLOW_DATA_RESERVED_KEYS.code,
|
|
4478
|
+
suggestion: FLOW_DATA_RESERVED_KEYS.suggestion
|
|
4479
|
+
});
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
|
|
4419
4483
|
// src/validators/saveDoor.ts
|
|
4420
4484
|
var TOOL_DISCOVERY_MODES = /* @__PURE__ */ new Set(["eager", "lazy", "off"]);
|
|
4421
4485
|
var TEMPLATE_ACTION_OPEN2 = "{{";
|
|
@@ -6878,6 +6942,7 @@ function validateParsed(flow, opts, sources) {
|
|
|
6878
6942
|
validateSaveDoorExtras(f, issues);
|
|
6879
6943
|
validateExecutorConfigEnvScopes(f, issues);
|
|
6880
6944
|
validateServerOwnedQueryKeys(f, issues);
|
|
6945
|
+
validateFlowDataKeys(f, issues);
|
|
6881
6946
|
validateCredentialEndpointPairing(f, issues);
|
|
6882
6947
|
validateExamples(f, issues);
|
|
6883
6948
|
validateOrchestratorExons(f, issues);
|