@vaudience/aigentflow-flow-validator 0.27.0 → 0.28.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 +64 -1
- package/README.md +3 -1
- package/dist/cli.js +281 -167
- package/dist/index.cjs +276 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +276 -165
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -251,7 +251,8 @@ interface Flow {
|
|
|
251
251
|
currency?: string;
|
|
252
252
|
max_duration?: string;
|
|
253
253
|
orchestrator?: OrchestratorDefinition;
|
|
254
|
-
|
|
254
|
+
/** Removed in AIgentFlow v2.836.0: any non-null value is `campaign_removed`. */
|
|
255
|
+
campaign?: unknown;
|
|
255
256
|
checkpoint?: Record<string, unknown>;
|
|
256
257
|
input_schema?: InputSchema;
|
|
257
258
|
classification?: Record<string, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -251,7 +251,8 @@ interface Flow {
|
|
|
251
251
|
currency?: string;
|
|
252
252
|
max_duration?: string;
|
|
253
253
|
orchestrator?: OrchestratorDefinition;
|
|
254
|
-
|
|
254
|
+
/** Removed in AIgentFlow v2.836.0: any non-null value is `campaign_removed`. */
|
|
255
|
+
campaign?: unknown;
|
|
255
256
|
checkpoint?: Record<string, unknown>;
|
|
256
257
|
input_schema?: InputSchema;
|
|
257
258
|
classification?: Record<string, unknown>;
|
package/dist/index.js
CHANGED
|
@@ -449,7 +449,7 @@ function validateBasicStructure(flow, issues) {
|
|
|
449
449
|
|
|
450
450
|
// src/spec/aigentflow-spec.json
|
|
451
451
|
var aigentflow_spec_default = {
|
|
452
|
-
specVersion: "2.
|
|
452
|
+
specVersion: "2.837.0",
|
|
453
453
|
inputSchemaVersion: 1,
|
|
454
454
|
executorSchemes: [
|
|
455
455
|
"a2a",
|
|
@@ -480,6 +480,7 @@ var aigentflow_spec_default = {
|
|
|
480
480
|
"messenger",
|
|
481
481
|
"mock",
|
|
482
482
|
"mqtt",
|
|
483
|
+
"nexus",
|
|
483
484
|
"opencorporates",
|
|
484
485
|
"openmeteo",
|
|
485
486
|
"overpass",
|
|
@@ -544,12 +545,9 @@ var aigentflow_spec_default = {
|
|
|
544
545
|
"step_failed",
|
|
545
546
|
"mission_started",
|
|
546
547
|
"mission_completed",
|
|
547
|
-
"dfm_suggestion",
|
|
548
548
|
"timer",
|
|
549
549
|
"request_turn",
|
|
550
550
|
"mission_recovered",
|
|
551
|
-
"campaign_child_completed",
|
|
552
|
-
"campaign_child_failed",
|
|
553
551
|
"human_response",
|
|
554
552
|
"human_input"
|
|
555
553
|
],
|
|
@@ -565,15 +563,6 @@ var aigentflow_spec_default = {
|
|
|
565
563
|
"aif_ask_human",
|
|
566
564
|
"aif_flow_list",
|
|
567
565
|
"aif_mission_reflect",
|
|
568
|
-
"aif_signal_complete",
|
|
569
|
-
"aif_signal_need_human",
|
|
570
|
-
"aif_signal_delegate",
|
|
571
|
-
"aif_signal_need_tool",
|
|
572
|
-
"aif_signal_modify_flow",
|
|
573
|
-
"aif_campaign_spawn",
|
|
574
|
-
"aif_campaign_status",
|
|
575
|
-
"aif_campaign_results",
|
|
576
|
-
"aif_campaign_cancel",
|
|
577
566
|
"aif_memory_plan",
|
|
578
567
|
"aif_memory_record",
|
|
579
568
|
"aif_memory_recall",
|
|
@@ -745,20 +734,10 @@ var aigentflow_spec_default = {
|
|
|
745
734
|
orchestratorToolAllow: {
|
|
746
735
|
warningField: "orchestrator.exons",
|
|
747
736
|
askHumanTool: "aif_ask_human",
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
"
|
|
752
|
-
"aif_signal_need_human",
|
|
753
|
-
"aif_signal_delegate",
|
|
754
|
-
"aif_signal_need_tool",
|
|
755
|
-
"aif_signal_modify_flow"
|
|
756
|
-
],
|
|
757
|
-
campaignTools: [
|
|
758
|
-
"aif_campaign_cancel",
|
|
759
|
-
"aif_campaign_results",
|
|
760
|
-
"aif_campaign_spawn",
|
|
761
|
-
"aif_campaign_status"
|
|
737
|
+
lifecycleTools: [
|
|
738
|
+
"aif_mission_complete",
|
|
739
|
+
"aif_mission_fail",
|
|
740
|
+
"aif_request_turn"
|
|
762
741
|
]
|
|
763
742
|
},
|
|
764
743
|
exons: {
|
|
@@ -788,7 +767,54 @@ var aigentflow_spec_default = {
|
|
|
788
767
|
schemeMessageFormat: "step %q uses %s://, which AIgentFlow no longer runs: its own agent chains were removed",
|
|
789
768
|
paramsMessageFormat: "step %q sets %s on ai://: AIgentFlow's own agent loop (agentic mode) was removed, so these parameters no longer exist",
|
|
790
769
|
flowKeyMessageFormat: "the flow-level key %q belonged to a removed agent surface and is no longer read",
|
|
791
|
-
suggestion:
|
|
770
|
+
suggestion: `Rebuild the step: a tool-using agent becomes nexus://agent/run (agent: "@org/name", prompt, capabilities); one tool becomes nexus://capability/<ref>; a plain prompt becomes ai://<provider>/chat or a prompt-only aiv://<org>/<name>. A nexus:// step acts as the person responsible for the run: who started it, who last saved its schedule or webhook trigger, or a flow:// child's parent. What cannot be converted: a run with no person (one started by a service or key that names nobody; share links no longer exist), and a step that needs an inline .exons spec, an arbitrary MCP server URL or signals. For those, start the flow from a person, a schedule or a trigger, or use a routine in Nexus`
|
|
771
|
+
},
|
|
772
|
+
removedSignalSurfaces: {
|
|
773
|
+
signalRemovedCode: "signal_removed",
|
|
774
|
+
flowModificationRemovedCode: "flow_modification_removed",
|
|
775
|
+
removedKeyIgnoredCode: "removed_key_ignored",
|
|
776
|
+
tools: [
|
|
777
|
+
"aif_signal_complete",
|
|
778
|
+
"aif_signal_need_human",
|
|
779
|
+
"aif_signal_delegate",
|
|
780
|
+
"aif_signal_need_tool",
|
|
781
|
+
"aif_signal_modify_flow"
|
|
782
|
+
],
|
|
783
|
+
triggers: [
|
|
784
|
+
"dfm_suggestion"
|
|
785
|
+
],
|
|
786
|
+
stepKey: "enable_signals",
|
|
787
|
+
stepKeyScheme: "aiv",
|
|
788
|
+
flowModificationStepKey: "flow_modification_allowed",
|
|
789
|
+
stepSkipSchemes: [
|
|
790
|
+
"flow"
|
|
791
|
+
],
|
|
792
|
+
enableSignalsMessage: "the orchestrator sets enable_signals: true: AIgentFlow's agent signals were removed in 2.834.0, so the tools it asks for no longer exist",
|
|
793
|
+
toolNamesMessageFormat: "%s names %s: AIgentFlow's agent signal tools were removed in 2.834.0",
|
|
794
|
+
stepKeyMessageFormat: "step %q sets enable_signals: AIgentFlow's agent signals were removed in 2.834.0, so the parameter no longer exists",
|
|
795
|
+
triggersMessage: "orchestrator.triggers names dfm_suggestion: dynamic flow modification was removed in 2.834.0, so nothing raises that trigger",
|
|
796
|
+
flowModificationStepMessageFormat: "step %q sets flow_modification_allowed: dynamic flow modification was removed in 2.834.0",
|
|
797
|
+
ignoredKeyMessageFormat: "%s is ignored: it configured AIgentFlow's agent signals / dynamic flow modification, removed in 2.834.0. AIgentFlow may have written this key into the flow itself; the flow runs as if it were absent",
|
|
798
|
+
ignoredKeySuggestion: "Remove the key; nothing reads it",
|
|
799
|
+
suggestion: "Signals and dynamic flow modification were removed in 2.834.0. aif_signal_need_human: add an async://human/<operation> step where the person must answer (inside a nexus://agent/run step, the atlas approval wait asks the person). aif_signal_delegate: run the other work as a flow:// step, or route with next: conditions. aif_signal_complete: an orchestrator ends the mission with aif_mission_complete. aif_signal_need_tool: no replacement; give the agent the capability in atlas. aif_signal_modify_flow, dfm_suggestion and flow_modification_allowed: no replacement; declare every step the flow may run and choose between them with next: conditions"
|
|
800
|
+
},
|
|
801
|
+
removedCampaignSurfaces: {
|
|
802
|
+
code: "campaign_removed",
|
|
803
|
+
flowKey: "campaign",
|
|
804
|
+
tools: [
|
|
805
|
+
"aif_campaign_spawn",
|
|
806
|
+
"aif_campaign_status",
|
|
807
|
+
"aif_campaign_results",
|
|
808
|
+
"aif_campaign_cancel"
|
|
809
|
+
],
|
|
810
|
+
triggers: [
|
|
811
|
+
"campaign_child_completed",
|
|
812
|
+
"campaign_child_failed"
|
|
813
|
+
],
|
|
814
|
+
blockMessage: "the flow declares a campaign: block: campaigns were removed in 2.836.0, so nothing would spawn or track its child missions",
|
|
815
|
+
toolNamesMessageFormat: "%s names %s: AIgentFlow's campaign tools were removed in 2.836.0",
|
|
816
|
+
triggersMessageFormat: "orchestrator.triggers names %s: campaigns were removed in 2.836.0, so no child mission raises that trigger",
|
|
817
|
+
suggestion: "Campaigns were removed in 2.836.0. Fan the work out inside one flow instead: a for_each step whose executor is flow://stored/<flow_id> runs the child flow once per item and hands the next step every result (.data.<step>, in item order), so a coordinator -> workers -> synthesiser campaign becomes a plan step -> a for_each over flow:// -> a synthesis step (a fixed set of different workers is next: parallel: with a rendezvous). When each worker is an agent, make the worker a nexus://agent/run step (the for_each step itself, or a step of the child flow): it runs as the person responsible for the run, and a flow:// child inherits its parent's. Delete the campaign: block, the aif_campaign_* tool names and the campaign_child_* triggers"
|
|
792
818
|
},
|
|
793
819
|
executorConfigEnvScopes: {
|
|
794
820
|
referencePrefix: "${",
|
|
@@ -1012,19 +1038,20 @@ var aigentflow_spec_default = {
|
|
|
1012
1038
|
]
|
|
1013
1039
|
},
|
|
1014
1040
|
atlasExecutor: {
|
|
1015
|
-
scheme: "
|
|
1041
|
+
scheme: "nexus",
|
|
1042
|
+
aliases: ["atlas"],
|
|
1016
1043
|
providerAgent: "agent",
|
|
1017
1044
|
providerCapability: "capability",
|
|
1018
1045
|
agentResource: "run",
|
|
1019
1046
|
capabilityRefPattern: "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
|
|
1020
1047
|
operationUnknown: {
|
|
1021
1048
|
code: "atlas_operation_unknown",
|
|
1022
|
-
messageFormat: "step %s uses %s, which is not
|
|
1023
|
-
suggestion: "Use
|
|
1049
|
+
messageFormat: "step %s uses %s, which is not a Nexus operation. The providers are agent (resource run) and capability (resource: a capability reference).",
|
|
1050
|
+
suggestion: "Use nexus://agent/run or nexus://capability/<capability-ref>."
|
|
1024
1051
|
},
|
|
1025
1052
|
agentMissing: {
|
|
1026
1053
|
code: "atlas_agent_missing",
|
|
1027
|
-
messageFormat: "step %s runs
|
|
1054
|
+
messageFormat: "step %s runs a Nexus agent but query.agent is missing, empty or not a string.",
|
|
1028
1055
|
suggestion: "Set query.agent to the agent to run, written out as a literal such as @acme/reporter."
|
|
1029
1056
|
},
|
|
1030
1057
|
agentNotLiteral: {
|
|
@@ -1039,7 +1066,7 @@ var aigentflow_spec_default = {
|
|
|
1039
1066
|
},
|
|
1040
1067
|
promptMissing: {
|
|
1041
1068
|
code: "atlas_prompt_missing",
|
|
1042
|
-
messageFormat: "step %s runs
|
|
1069
|
+
messageFormat: "step %s runs a Nexus agent with neither query.prompt nor query.prompt_template.",
|
|
1043
1070
|
suggestion: "Set exactly one of query.prompt or query.prompt_template."
|
|
1044
1071
|
},
|
|
1045
1072
|
promptBoth: {
|
|
@@ -1049,7 +1076,7 @@ var aigentflow_spec_default = {
|
|
|
1049
1076
|
},
|
|
1050
1077
|
capabilityRefInvalid: {
|
|
1051
1078
|
code: "atlas_capability_ref_invalid",
|
|
1052
|
-
messageFormat: "step %s uses
|
|
1079
|
+
messageFormat: "step %s uses nexus://capability/%s, which is not a valid capability reference.",
|
|
1053
1080
|
suggestion: "A capability reference starts with a letter or digit and continues with letters, digits, _ and - up to 128 characters in all."
|
|
1054
1081
|
},
|
|
1055
1082
|
modelNotLiteral: {
|
|
@@ -1576,20 +1603,6 @@ var aigentflow_spec_default = {
|
|
|
1576
1603
|
BillingConfig: {
|
|
1577
1604
|
max_credits: "scalar"
|
|
1578
1605
|
},
|
|
1579
|
-
CampaignChildFlowDef: {
|
|
1580
|
-
alias: "scalar",
|
|
1581
|
-
flow_id: "scalar",
|
|
1582
|
-
flow_name: "scalar"
|
|
1583
|
-
},
|
|
1584
|
-
CampaignConfig: {
|
|
1585
|
-
child_flows: "list<CampaignChildFlowDef>",
|
|
1586
|
-
max_concurrent: "scalar",
|
|
1587
|
-
max_credits_per_child: "scalar",
|
|
1588
|
-
max_depth: "scalar",
|
|
1589
|
-
max_total_children: "scalar",
|
|
1590
|
-
on_children_complete: "scalar",
|
|
1591
|
-
shared_memory: "scalar"
|
|
1592
|
-
},
|
|
1593
1606
|
Checkpoint: {
|
|
1594
1607
|
exact: "map<any>",
|
|
1595
1608
|
fields: "map<FieldMatcher>",
|
|
@@ -1723,7 +1736,7 @@ var aigentflow_spec_default = {
|
|
|
1723
1736
|
Flow: {
|
|
1724
1737
|
aigentflow_version: "scalar",
|
|
1725
1738
|
billing: "BillingConfig",
|
|
1726
|
-
campaign: "
|
|
1739
|
+
campaign: "any",
|
|
1727
1740
|
checkpoint: "CheckpointConfig",
|
|
1728
1741
|
classification: "FlowClassification",
|
|
1729
1742
|
compliance: "FlowCompliance",
|
|
@@ -2033,10 +2046,7 @@ var KNOWN_KEYS = aigentflow_spec_default.knownKeys;
|
|
|
2033
2046
|
var ORCHESTRATOR_TOOL_ALLOW = {
|
|
2034
2047
|
warningField: aigentflow_spec_default.orchestratorToolAllow.warningField,
|
|
2035
2048
|
askHumanTool: aigentflow_spec_default.orchestratorToolAllow.askHumanTool,
|
|
2036
|
-
|
|
2037
|
-
lifecycleTools: aigentflow_spec_default.orchestratorToolAllow.lifecycleTools,
|
|
2038
|
-
signalTools: aigentflow_spec_default.orchestratorToolAllow.signalTools,
|
|
2039
|
-
campaignTools: aigentflow_spec_default.orchestratorToolAllow.campaignTools
|
|
2049
|
+
lifecycleTools: aigentflow_spec_default.orchestratorToolAllow.lifecycleTools
|
|
2040
2050
|
};
|
|
2041
2051
|
var EXONS = {
|
|
2042
2052
|
/** The YAML frontmatter delimiter line. */
|
|
@@ -2055,6 +2065,45 @@ var REMOVED_AGENT_SURFACES = {
|
|
|
2055
2065
|
flowKeyMessageFormat: removed.flowKeyMessageFormat,
|
|
2056
2066
|
suggestion: removed.suggestion
|
|
2057
2067
|
};
|
|
2068
|
+
var signal = aigentflow_spec_default.removedSignalSurfaces;
|
|
2069
|
+
var REMOVED_SIGNAL_SURFACES = {
|
|
2070
|
+
signalRemovedCode: signal.signalRemovedCode,
|
|
2071
|
+
flowModificationRemovedCode: signal.flowModificationRemovedCode,
|
|
2072
|
+
removedKeyIgnoredCode: signal.removedKeyIgnoredCode,
|
|
2073
|
+
tools: signal.tools,
|
|
2074
|
+
triggers: signal.triggers,
|
|
2075
|
+
stepKey: signal.stepKey,
|
|
2076
|
+
stepKeyScheme: signal.stepKeyScheme,
|
|
2077
|
+
flowModificationStepKey: signal.flowModificationStepKey,
|
|
2078
|
+
stepSkipSchemes: new Set(signal.stepSkipSchemes),
|
|
2079
|
+
enableSignalsMessage: signal.enableSignalsMessage,
|
|
2080
|
+
toolNamesMessageFormat: signal.toolNamesMessageFormat,
|
|
2081
|
+
stepKeyMessageFormat: signal.stepKeyMessageFormat,
|
|
2082
|
+
triggersMessage: signal.triggersMessage,
|
|
2083
|
+
flowModificationStepMessageFormat: signal.flowModificationStepMessageFormat,
|
|
2084
|
+
ignoredKeyMessageFormat: signal.ignoredKeyMessageFormat,
|
|
2085
|
+
ignoredKeySuggestion: signal.ignoredKeySuggestion,
|
|
2086
|
+
suggestion: signal.suggestion
|
|
2087
|
+
};
|
|
2088
|
+
var campaign = aigentflow_spec_default.removedCampaignSurfaces;
|
|
2089
|
+
var REMOVED_CAMPAIGN_SURFACES = {
|
|
2090
|
+
code: campaign.code,
|
|
2091
|
+
flowKey: campaign.flowKey,
|
|
2092
|
+
tools: campaign.tools,
|
|
2093
|
+
triggers: campaign.triggers,
|
|
2094
|
+
blockMessage: campaign.blockMessage,
|
|
2095
|
+
toolNamesMessageFormat: campaign.toolNamesMessageFormat,
|
|
2096
|
+
triggersMessageFormat: campaign.triggersMessageFormat,
|
|
2097
|
+
suggestion: campaign.suggestion
|
|
2098
|
+
};
|
|
2099
|
+
var REMOVED_ORCHESTRATOR_TOOLS = /* @__PURE__ */ new Set([
|
|
2100
|
+
...signal.tools,
|
|
2101
|
+
...campaign.tools
|
|
2102
|
+
]);
|
|
2103
|
+
var REMOVED_ORCHESTRATOR_TRIGGERS = /* @__PURE__ */ new Set([
|
|
2104
|
+
...signal.triggers,
|
|
2105
|
+
...campaign.triggers
|
|
2106
|
+
]);
|
|
2058
2107
|
var EXECUTOR_CONFIG_ENV_SCOPES = {
|
|
2059
2108
|
referencePrefix: aigentflow_spec_default.executorConfigEnvScopes.referencePrefix,
|
|
2060
2109
|
referenceSuffix: aigentflow_spec_default.executorConfigEnvScopes.referenceSuffix,
|
|
@@ -2147,7 +2196,8 @@ var FUNCTION_OPERATIONS = {
|
|
|
2147
2196
|
};
|
|
2148
2197
|
var atlas = aigentflow_spec_default.atlasExecutor;
|
|
2149
2198
|
var ATLAS_EXECUTOR = {
|
|
2150
|
-
scheme:
|
|
2199
|
+
/** The canonical scheme (nexus) and its aliases (atlas): one set of rules. */
|
|
2200
|
+
schemes: /* @__PURE__ */ new Set([atlas.scheme, ...atlas.aliases]),
|
|
2151
2201
|
providerAgent: atlas.providerAgent,
|
|
2152
2202
|
providerCapability: atlas.providerCapability,
|
|
2153
2203
|
agentResource: atlas.agentResource,
|
|
@@ -2359,16 +2409,14 @@ function validateOrchestratorExons(flow, issues) {
|
|
|
2359
2409
|
suggestion: "Remove requirements.resources, and narrow the agent with tools.mcp_servers and tools.allow"
|
|
2360
2410
|
});
|
|
2361
2411
|
}
|
|
2362
|
-
warnOrchestratorToolWithheld(
|
|
2412
|
+
warnOrchestratorToolWithheld(orch, report, issues);
|
|
2363
2413
|
}
|
|
2364
|
-
function warnOrchestratorToolWithheld(
|
|
2414
|
+
function warnOrchestratorToolWithheld(orch, report, issues) {
|
|
2365
2415
|
if (!report.toolsAllowDeclared) return;
|
|
2366
2416
|
const cfg = ORCHESTRATOR_TOOL_ALLOW;
|
|
2367
2417
|
const exempt = new Set(cfg.lifecycleTools);
|
|
2368
|
-
const signals = typeof orch.enable_signals === "boolean" ? orch.enable_signals : cfg.enableSignalsDefault;
|
|
2369
|
-
if (signals) for (const t of cfg.signalTools) exempt.add(t);
|
|
2370
2418
|
const allow = new Set(report.toolsAllow);
|
|
2371
|
-
const withheld = (name) => !allow.has(name) && !exempt.has(name);
|
|
2419
|
+
const withheld = (name) => !allow.has(name) && !exempt.has(name) && !REMOVED_ORCHESTRATOR_TOOLS.has(name);
|
|
2372
2420
|
const warn = (message) => issues.warn({ field: cfg.warningField, code: CODE_TOOL_WITHHELD, message });
|
|
2373
2421
|
const named = [];
|
|
2374
2422
|
if (isArray(orch.tools)) {
|
|
@@ -2391,11 +2439,6 @@ function warnOrchestratorToolWithheld(flow, orch, report, issues) {
|
|
|
2391
2439
|
`the orchestrator's exons definition has a tools.allow list that does not name ${cfg.askHumanTool}, so this orchestrator can never ask a person a question: human intervention is off. Add ${cfg.askHumanTool} to tools.allow if a human should be reachable, or ignore this if the orchestrator is meant to run unattended.`
|
|
2392
2440
|
);
|
|
2393
2441
|
}
|
|
2394
|
-
if (isRecord(flow.campaign) && !cfg.campaignTools.some((name) => !withheld(name))) {
|
|
2395
|
-
warn(
|
|
2396
|
-
`this flow declares a campaign, but the orchestrator's exons definition has a tools.allow list that names none of the campaign tools (${cfg.campaignTools.join(", ")}), so no child mission can be spawned or tracked. Add the campaign tools the orchestrator needs to tools.allow.`
|
|
2397
|
-
);
|
|
2398
|
-
}
|
|
2399
2442
|
}
|
|
2400
2443
|
|
|
2401
2444
|
// src/validators/executors.ts
|
|
@@ -2512,9 +2555,9 @@ function validateRemovedFlowKeys(flow, issues) {
|
|
|
2512
2555
|
}
|
|
2513
2556
|
function checkAtlasStep(executor, query, stepField, stepID, issues) {
|
|
2514
2557
|
if (executor.includes(TEMPLATE_ACTION_OPEN)) return;
|
|
2515
|
-
const
|
|
2516
|
-
if (!executor.
|
|
2517
|
-
const rest = executor.slice(
|
|
2558
|
+
const sep = executor.indexOf(SCHEME_SEPARATOR);
|
|
2559
|
+
if (sep < 0 || !ATLAS_EXECUTOR.schemes.has(executor.slice(0, sep))) return;
|
|
2560
|
+
const rest = executor.slice(sep + SCHEME_SEPARATOR.length);
|
|
2518
2561
|
const slash = rest.indexOf("/");
|
|
2519
2562
|
const provider = slash < 0 ? rest : rest.slice(0, slash);
|
|
2520
2563
|
const resource = slash < 0 ? "" : rest.slice(slash + 1);
|
|
@@ -3727,49 +3770,6 @@ function flowHasOrchestratorYieldEdge(flow) {
|
|
|
3727
3770
|
}
|
|
3728
3771
|
return false;
|
|
3729
3772
|
}
|
|
3730
|
-
var GO_INT64_FLOAT_LIMIT = 2 ** 63;
|
|
3731
|
-
function decodeGoInt(v) {
|
|
3732
|
-
if (typeof v !== "number" || Number.isNaN(v)) return null;
|
|
3733
|
-
if (v >= GO_INT64_FLOAT_LIMIT) return null;
|
|
3734
|
-
if (v === -Infinity) return -GO_INT64_FLOAT_LIMIT;
|
|
3735
|
-
return Math.trunc(v);
|
|
3736
|
-
}
|
|
3737
|
-
function validateCampaignChildFlows(campaign, issues) {
|
|
3738
|
-
const field = "campaign.child_flows";
|
|
3739
|
-
const raw = campaign.child_flows;
|
|
3740
|
-
if (raw !== void 0 && raw !== null && !Array.isArray(raw)) {
|
|
3741
|
-
issues.error({ field, message: "campaign.child_flows must be a list", code: "invalid_type" });
|
|
3742
|
-
return;
|
|
3743
|
-
}
|
|
3744
|
-
const entries = (Array.isArray(raw) ? raw : []).map((entry, i) => ({ entry, i })).filter(({ entry }) => entry !== null);
|
|
3745
|
-
if (entries.length === 0) {
|
|
3746
|
-
issues.error({
|
|
3747
|
-
field,
|
|
3748
|
-
message: "campaign requires at least one entry in child_flows",
|
|
3749
|
-
code: "campaign_no_child_flows"
|
|
3750
|
-
});
|
|
3751
|
-
return;
|
|
3752
|
-
}
|
|
3753
|
-
for (const { entry, i } of entries) {
|
|
3754
|
-
if (!isRecord(entry)) {
|
|
3755
|
-
issues.error({
|
|
3756
|
-
field: `${field}[${i}]`,
|
|
3757
|
-
message: "each campaign.child_flows entry must be a mapping",
|
|
3758
|
-
code: "invalid_type"
|
|
3759
|
-
});
|
|
3760
|
-
continue;
|
|
3761
|
-
}
|
|
3762
|
-
const id = issues.stringOf(entry, "flow_id", `${field}[${i}]`);
|
|
3763
|
-
const name = issues.stringOf(entry, "flow_name", `${field}[${i}]`);
|
|
3764
|
-
if (id !== null && id !== "" || name !== null && name !== "") continue;
|
|
3765
|
-
issues.error({
|
|
3766
|
-
field: `${field}[${i}]`,
|
|
3767
|
-
message: `campaign.child_flows[${i}] needs a flow_id or a flow_name`,
|
|
3768
|
-
code: "campaign_child_flow_no_id",
|
|
3769
|
-
suggestion: "Name the child flow with flow_name, or pin it with flow_id"
|
|
3770
|
-
});
|
|
3771
|
-
}
|
|
3772
|
-
}
|
|
3773
3773
|
function validateOrchestratorCampaign(flow, issues, opts) {
|
|
3774
3774
|
const hasOrchestrator = isRecord(flow.orchestrator);
|
|
3775
3775
|
if (hasOrchestrator) {
|
|
@@ -3825,6 +3825,7 @@ function validateOrchestratorCampaign(flow, issues, opts) {
|
|
|
3825
3825
|
const trigger = rawTrigger;
|
|
3826
3826
|
const base = `orchestrator.triggers[${i}]`;
|
|
3827
3827
|
const type = issues.stringOf(trigger, "type", base);
|
|
3828
|
+
if (type !== null && REMOVED_ORCHESTRATOR_TRIGGERS.has(type)) return;
|
|
3828
3829
|
if (type === null || !ORCHESTRATOR_TRIGGERS.has(type)) {
|
|
3829
3830
|
issues.error({
|
|
3830
3831
|
field: `${base}.type`,
|
|
@@ -3855,7 +3856,9 @@ function validateOrchestratorCampaign(flow, issues, opts) {
|
|
|
3855
3856
|
if (Array.isArray(orch.tools)) {
|
|
3856
3857
|
orch.tools.forEach((raw, i) => {
|
|
3857
3858
|
const tool = issues.stringAt(raw, `orchestrator.tools[${i}]`);
|
|
3858
|
-
if (tool === null || ORCHESTRATOR_TOOLS.has(tool))
|
|
3859
|
+
if (tool === null || ORCHESTRATOR_TOOLS.has(tool) || REMOVED_ORCHESTRATOR_TOOLS.has(tool)) {
|
|
3860
|
+
return;
|
|
3861
|
+
}
|
|
3859
3862
|
const finding = {
|
|
3860
3863
|
field: `orchestrator.tools[${i}]`,
|
|
3861
3864
|
message: `Unrecognised orchestrator tool name '${tool}'`,
|
|
@@ -3876,47 +3879,6 @@ function validateOrchestratorCampaign(flow, issues, opts) {
|
|
|
3876
3879
|
});
|
|
3877
3880
|
}
|
|
3878
3881
|
}
|
|
3879
|
-
if (flow.campaign !== void 0 && flow.campaign !== null) {
|
|
3880
|
-
if (!hasOrchestrator) {
|
|
3881
|
-
issues.error({
|
|
3882
|
-
field: "campaign",
|
|
3883
|
-
message: "campaign requires an orchestrator block",
|
|
3884
|
-
code: "campaign_requires_orchestrator"
|
|
3885
|
-
});
|
|
3886
|
-
}
|
|
3887
|
-
const campaign = flow.campaign;
|
|
3888
|
-
if (isRecord(campaign)) {
|
|
3889
|
-
const cap = campaign.max_credits_per_child;
|
|
3890
|
-
if (cap !== void 0 && cap !== null) {
|
|
3891
|
-
const decoded = decodeGoInt(cap);
|
|
3892
|
-
if (decoded === null) {
|
|
3893
|
-
issues.error({
|
|
3894
|
-
field: "campaign.max_credits_per_child",
|
|
3895
|
-
message: `campaign.max_credits_per_child must be a number of credits, got '${String(cap)}'`,
|
|
3896
|
-
code: "invalid_type"
|
|
3897
|
-
});
|
|
3898
|
-
} else if (decoded < 0) {
|
|
3899
|
-
issues.error({
|
|
3900
|
-
field: "campaign.max_credits_per_child",
|
|
3901
|
-
message: "campaign: max_credits_per_child must be >= 0",
|
|
3902
|
-
code: "campaign_invalid_max_credits_per_child"
|
|
3903
|
-
});
|
|
3904
|
-
}
|
|
3905
|
-
}
|
|
3906
|
-
validateCampaignChildFlows(campaign, issues);
|
|
3907
|
-
}
|
|
3908
|
-
const target = isRecord(campaign) ? issues.stringOf(campaign, "on_children_complete", "campaign") : null;
|
|
3909
|
-
if (target !== null && target !== "") {
|
|
3910
|
-
const steps = isRecord(flow.steps) ? flow.steps : {};
|
|
3911
|
-
if (!(target in steps)) {
|
|
3912
|
-
issues.error({
|
|
3913
|
-
field: "campaign.on_children_complete",
|
|
3914
|
-
message: `campaign.on_children_complete references unknown step '${target}'`,
|
|
3915
|
-
code: "campaign_handoff_step_unknown"
|
|
3916
|
-
});
|
|
3917
|
-
}
|
|
3918
|
-
}
|
|
3919
|
-
}
|
|
3920
3882
|
}
|
|
3921
3883
|
|
|
3922
3884
|
// src/validators/credentialBindings.ts
|
|
@@ -5042,10 +5004,6 @@ var CODE_UNKNOWN_YAML_KEY = "unknown_yaml_key";
|
|
|
5042
5004
|
var KEY_BUDGET = "budget";
|
|
5043
5005
|
var KEY_MAX_RETRIES = "max_retries";
|
|
5044
5006
|
var REMOVED_IN = "v2.721.0";
|
|
5045
|
-
var KEY_BUDGET_MAX_PER_CHILD = "budget_max_per_child";
|
|
5046
|
-
var BUDGET_MAX_PER_CHILD_REMOVED_IN = "v2.728.0";
|
|
5047
|
-
var BUDGET_MAX_PER_CHILD_MESSAGE = `\`campaign.budget_max_per_child\` (USD) was removed from the grammar in AIgentFlow ${BUDGET_MAX_PER_CHILD_REMOVED_IN} because it capped nothing, and AIgentFlow refuses to save a flow that declares it.`;
|
|
5048
|
-
var BUDGET_MAX_PER_CHILD_SUGGESTION = "Use `campaign.max_credits_per_child: N` (a whole number of credits) \u2014 it is checked before each agentic turn of a child, and a spawn may lower it with `max_credits`.";
|
|
5049
5007
|
var BUDGET_MESSAGE = `The flow-level \`budget:\` key was removed from the grammar in AIgentFlow ${REMOVED_IN} because nothing read it (it limited no spend), and AIgentFlow refuses to save a flow that declares it.`;
|
|
5050
5008
|
var BUDGET_SUGGESTION = "Delete it. To cap spend use `billing: { max_credits: N }` \u2014 it caps the credit reservation and refuses further agentic turns (agentic ai://, exons://, the orchestrator); plain chat steps and flow:// sub-flows are not checked against it.";
|
|
5051
5009
|
function maxRetriesMessage(owner) {
|
|
@@ -5073,15 +5031,6 @@ function validateRetiredKeys(flow, issues) {
|
|
|
5073
5031
|
suggestion: MAX_RETRIES_SUGGESTION
|
|
5074
5032
|
});
|
|
5075
5033
|
}
|
|
5076
|
-
const campaign = root.campaign;
|
|
5077
|
-
if (isRecord(campaign) && declares(campaign, KEY_BUDGET_MAX_PER_CHILD)) {
|
|
5078
|
-
issues.error({
|
|
5079
|
-
field: `campaign.${KEY_BUDGET_MAX_PER_CHILD}`,
|
|
5080
|
-
message: BUDGET_MAX_PER_CHILD_MESSAGE,
|
|
5081
|
-
code: CODE_UNKNOWN_YAML_KEY,
|
|
5082
|
-
suggestion: BUDGET_MAX_PER_CHILD_SUGGESTION
|
|
5083
|
-
});
|
|
5084
|
-
}
|
|
5085
5034
|
const steps = flow.steps;
|
|
5086
5035
|
if (!isRecord(steps)) return;
|
|
5087
5036
|
for (const [stepID, rawStep] of Object.entries(steps)) {
|
|
@@ -5907,6 +5856,167 @@ function validateFamilies(flow, steps, issues) {
|
|
|
5907
5856
|
}
|
|
5908
5857
|
}
|
|
5909
5858
|
|
|
5859
|
+
// src/validators/removedSignalCampaign.ts
|
|
5860
|
+
var TEMPLATE_ACTION_OPEN3 = "{{";
|
|
5861
|
+
function fill(format, ...args) {
|
|
5862
|
+
let i = 0;
|
|
5863
|
+
return format.replace(/%[qs]/g, () => args[i++] ?? "");
|
|
5864
|
+
}
|
|
5865
|
+
function stringEntries(m, key) {
|
|
5866
|
+
const raw = m[key];
|
|
5867
|
+
return Array.isArray(raw) ? raw.filter((v) => typeof v === "string") : [];
|
|
5868
|
+
}
|
|
5869
|
+
function triggerTypes(orch) {
|
|
5870
|
+
const raw = orch.triggers;
|
|
5871
|
+
if (!Array.isArray(raw)) return [];
|
|
5872
|
+
const out = [];
|
|
5873
|
+
for (const t of raw) {
|
|
5874
|
+
if (isRecord(t) && typeof t.type === "string") out.push(t.type);
|
|
5875
|
+
}
|
|
5876
|
+
return out;
|
|
5877
|
+
}
|
|
5878
|
+
function namesIn(names, removed2) {
|
|
5879
|
+
const found = [];
|
|
5880
|
+
for (const name of names) {
|
|
5881
|
+
if (removed2.includes(name) && !found.includes(name)) found.push(name);
|
|
5882
|
+
}
|
|
5883
|
+
return found;
|
|
5884
|
+
}
|
|
5885
|
+
function orchestratorToolsAllow(orch) {
|
|
5886
|
+
const source = orch.exons;
|
|
5887
|
+
if (typeof source !== "string" || source === "") return [];
|
|
5888
|
+
const report = inspectExonsFrontmatter(source);
|
|
5889
|
+
if (report.parseError !== null || !report.specRead || !report.toolsAllowDeclared) return [];
|
|
5890
|
+
return [...report.toolsAllow];
|
|
5891
|
+
}
|
|
5892
|
+
function validateRemovedOrchestratorSurfaces(flow, issues) {
|
|
5893
|
+
const sig = REMOVED_SIGNAL_SURFACES;
|
|
5894
|
+
const camp = REMOVED_CAMPAIGN_SURFACES;
|
|
5895
|
+
const orch = isRecord(flow.orchestrator) ? flow.orchestrator : null;
|
|
5896
|
+
const lists = orch === null ? [] : [
|
|
5897
|
+
...["tools", "deny_tools", "require_approval_for"].map((key) => ({
|
|
5898
|
+
field: `orchestrator.${key}`,
|
|
5899
|
+
names: stringEntries(orch, key)
|
|
5900
|
+
})),
|
|
5901
|
+
{ field: "orchestrator.exons", names: orchestratorToolsAllow(orch) }
|
|
5902
|
+
];
|
|
5903
|
+
if (orch !== null) {
|
|
5904
|
+
if (orch.enable_signals === true) {
|
|
5905
|
+
issues.error({
|
|
5906
|
+
field: "orchestrator.enable_signals",
|
|
5907
|
+
code: sig.signalRemovedCode,
|
|
5908
|
+
message: sig.enableSignalsMessage,
|
|
5909
|
+
suggestion: sig.suggestion
|
|
5910
|
+
});
|
|
5911
|
+
}
|
|
5912
|
+
for (const list of lists) {
|
|
5913
|
+
const named = namesIn(list.names, sig.tools);
|
|
5914
|
+
if (named.length === 0) continue;
|
|
5915
|
+
issues.error({
|
|
5916
|
+
field: list.field,
|
|
5917
|
+
code: sig.signalRemovedCode,
|
|
5918
|
+
message: fill(sig.toolNamesMessageFormat, list.field, named.join(", ")),
|
|
5919
|
+
suggestion: sig.suggestion
|
|
5920
|
+
});
|
|
5921
|
+
}
|
|
5922
|
+
if (namesIn(triggerTypes(orch), sig.triggers).length > 0) {
|
|
5923
|
+
issues.error({
|
|
5924
|
+
field: "orchestrator.triggers",
|
|
5925
|
+
code: sig.flowModificationRemovedCode,
|
|
5926
|
+
message: sig.triggersMessage,
|
|
5927
|
+
suggestion: sig.suggestion
|
|
5928
|
+
});
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
const block = flow[camp.flowKey];
|
|
5932
|
+
if (block !== void 0 && block !== null) {
|
|
5933
|
+
issues.error({
|
|
5934
|
+
field: camp.flowKey,
|
|
5935
|
+
code: camp.code,
|
|
5936
|
+
message: camp.blockMessage,
|
|
5937
|
+
suggestion: camp.suggestion
|
|
5938
|
+
});
|
|
5939
|
+
}
|
|
5940
|
+
if (orch !== null) {
|
|
5941
|
+
for (const list of lists) {
|
|
5942
|
+
const named = namesIn(list.names, camp.tools);
|
|
5943
|
+
if (named.length === 0) continue;
|
|
5944
|
+
issues.error({
|
|
5945
|
+
field: list.field,
|
|
5946
|
+
code: camp.code,
|
|
5947
|
+
message: fill(camp.toolNamesMessageFormat, list.field, named.join(", ")),
|
|
5948
|
+
suggestion: camp.suggestion
|
|
5949
|
+
});
|
|
5950
|
+
}
|
|
5951
|
+
const triggers = namesIn(triggerTypes(orch), camp.triggers);
|
|
5952
|
+
if (triggers.length > 0) {
|
|
5953
|
+
issues.error({
|
|
5954
|
+
field: "orchestrator.triggers",
|
|
5955
|
+
code: camp.code,
|
|
5956
|
+
message: fill(camp.triggersMessageFormat, triggers.join(", ")),
|
|
5957
|
+
suggestion: camp.suggestion
|
|
5958
|
+
});
|
|
5959
|
+
}
|
|
5960
|
+
}
|
|
5961
|
+
const judgeStep = (executor, query, field, stepID) => {
|
|
5962
|
+
if (typeof executor !== "string" || executor === "") return;
|
|
5963
|
+
if (executor.includes(TEMPLATE_ACTION_OPEN3)) return;
|
|
5964
|
+
const scheme = removedExecutorScheme(executor);
|
|
5965
|
+
if (REMOVED_AGENT_SURFACES.schemes.has(scheme) || sig.stepSkipSchemes.has(scheme)) return;
|
|
5966
|
+
if (!isRecord(query)) return;
|
|
5967
|
+
const quoted = JSON.stringify(stepID);
|
|
5968
|
+
if (Object.prototype.hasOwnProperty.call(query, sig.flowModificationStepKey)) {
|
|
5969
|
+
issues.error({
|
|
5970
|
+
field,
|
|
5971
|
+
code: sig.flowModificationRemovedCode,
|
|
5972
|
+
stepId: stepID,
|
|
5973
|
+
message: fill(sig.flowModificationStepMessageFormat, quoted),
|
|
5974
|
+
suggestion: sig.suggestion
|
|
5975
|
+
});
|
|
5976
|
+
}
|
|
5977
|
+
if (scheme === sig.stepKeyScheme && Object.prototype.hasOwnProperty.call(query, sig.stepKey)) {
|
|
5978
|
+
issues.error({
|
|
5979
|
+
field,
|
|
5980
|
+
code: sig.signalRemovedCode,
|
|
5981
|
+
stepId: stepID,
|
|
5982
|
+
message: fill(sig.stepKeyMessageFormat, quoted),
|
|
5983
|
+
suggestion: sig.suggestion
|
|
5984
|
+
});
|
|
5985
|
+
}
|
|
5986
|
+
};
|
|
5987
|
+
const steps = flow.steps;
|
|
5988
|
+
if (isRecord(steps)) {
|
|
5989
|
+
for (const stepID of Object.keys(steps).sort()) {
|
|
5990
|
+
const step = steps[stepID];
|
|
5991
|
+
if (!isRecord(step)) continue;
|
|
5992
|
+
judgeStep(step.executor, step.query, `steps.${stepID}`, stepID);
|
|
5993
|
+
const loop = step.loop;
|
|
5994
|
+
if (!isRecord(loop) || !Array.isArray(loop.steps)) continue;
|
|
5995
|
+
loop.steps.forEach((sub, i) => {
|
|
5996
|
+
if (!isRecord(sub)) return;
|
|
5997
|
+
const subID = issues.stringOf(sub, "id", `steps.${stepID}.loop.steps[${i}]`) ?? String(i);
|
|
5998
|
+
judgeStep(
|
|
5999
|
+
sub.executor,
|
|
6000
|
+
sub.query,
|
|
6001
|
+
`steps.${stepID}.loop.steps[${i}]`,
|
|
6002
|
+
`${stepID}.${subID}`
|
|
6003
|
+
);
|
|
6004
|
+
});
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
const ignored = (field) => issues.warn({
|
|
6008
|
+
field,
|
|
6009
|
+
code: sig.removedKeyIgnoredCode,
|
|
6010
|
+
message: fill(sig.ignoredKeyMessageFormat, field),
|
|
6011
|
+
suggestion: sig.ignoredKeySuggestion
|
|
6012
|
+
});
|
|
6013
|
+
if (orch !== null && orch.enable_signals === false) ignored("orchestrator.enable_signals");
|
|
6014
|
+
const checkpoint = flow.checkpoint;
|
|
6015
|
+
if (isRecord(checkpoint) && checkpoint.pre_dfm !== void 0 && checkpoint.pre_dfm !== null) {
|
|
6016
|
+
ignored("checkpoint.pre_dfm");
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
6019
|
+
|
|
5910
6020
|
// src/validators/complianceResidency.ts
|
|
5911
6021
|
function own2(m, key) {
|
|
5912
6022
|
if (!isRecord(m) || !Object.prototype.hasOwnProperty.call(m, key)) return void 0;
|
|
@@ -7387,6 +7497,7 @@ function validateParsed(flow, opts, sources) {
|
|
|
7387
7497
|
validateCredentialEndpointPairing(f, issues);
|
|
7388
7498
|
validateExamples(f, issues);
|
|
7389
7499
|
validateOrchestratorExons(f, issues);
|
|
7500
|
+
validateRemovedOrchestratorSurfaces(f, issues);
|
|
7390
7501
|
validateResidencyEnforcement(f, issues);
|
|
7391
7502
|
validateUnknownKeys(f, issues);
|
|
7392
7503
|
const templateStats = validateTemplates(f, issues, opts);
|