agent-contracts 0.12.3 → 0.13.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/README.md +71 -20
- package/dist/cli.js +770 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +89 -5
- package/dist/index.js +756 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -49864,7 +49864,7 @@ var require_dist12 = __commonJS({
|
|
|
49864
49864
|
var draft4MetaSchema = require_json_schema_draft_04();
|
|
49865
49865
|
var META_SUPPORT_DATA = ["/properties"];
|
|
49866
49866
|
var META_SCHEMA_ID = "http://json-schema.org/draft-04/schema";
|
|
49867
|
-
var
|
|
49867
|
+
var Ajv3 = class extends core_1.default {
|
|
49868
49868
|
constructor(opts = {}) {
|
|
49869
49869
|
super({
|
|
49870
49870
|
...opts,
|
|
@@ -49889,9 +49889,9 @@ var require_dist12 = __commonJS({
|
|
|
49889
49889
|
return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
|
|
49890
49890
|
}
|
|
49891
49891
|
};
|
|
49892
|
-
module.exports = exports =
|
|
49892
|
+
module.exports = exports = Ajv3;
|
|
49893
49893
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49894
|
-
exports.default =
|
|
49894
|
+
exports.default = Ajv3;
|
|
49895
49895
|
var core_2 = __require("ajv/dist/core");
|
|
49896
49896
|
Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
|
|
49897
49897
|
return core_2.KeywordCxt;
|
|
@@ -50088,8 +50088,8 @@ var require_ajv2 = __commonJS({
|
|
|
50088
50088
|
log: console.log,
|
|
50089
50089
|
error: console.error
|
|
50090
50090
|
};
|
|
50091
|
-
function createAjvInstance(
|
|
50092
|
-
const ajv2 = new
|
|
50091
|
+
function createAjvInstance(Ajv3, allErrors) {
|
|
50092
|
+
const ajv2 = new Ajv3({
|
|
50093
50093
|
allErrors,
|
|
50094
50094
|
meta: true,
|
|
50095
50095
|
messages: true,
|
|
@@ -50102,22 +50102,22 @@ var require_ajv2 = __commonJS({
|
|
|
50102
50102
|
if (allErrors) {
|
|
50103
50103
|
(0, ajv_errors_1.default)(ajv2);
|
|
50104
50104
|
}
|
|
50105
|
-
if (
|
|
50105
|
+
if (Ajv3 === ajv_1.default) {
|
|
50106
50106
|
ajv2.addSchema(draft4MetaSchema);
|
|
50107
50107
|
ajv2.addSchema(draft6MetaSchema);
|
|
50108
50108
|
}
|
|
50109
50109
|
return ajv2;
|
|
50110
50110
|
}
|
|
50111
|
-
function _createAjvInstances(
|
|
50111
|
+
function _createAjvInstances(Ajv3) {
|
|
50112
50112
|
let _default;
|
|
50113
50113
|
let _allErrors;
|
|
50114
50114
|
return {
|
|
50115
50115
|
get default() {
|
|
50116
|
-
_default !== null && _default !== void 0 ? _default : _default = createAjvInstance(
|
|
50116
|
+
_default !== null && _default !== void 0 ? _default : _default = createAjvInstance(Ajv3, false);
|
|
50117
50117
|
return _default;
|
|
50118
50118
|
},
|
|
50119
50119
|
get allErrors() {
|
|
50120
|
-
_allErrors !== null && _allErrors !== void 0 ? _allErrors : _allErrors = createAjvInstance(
|
|
50120
|
+
_allErrors !== null && _allErrors !== void 0 ? _allErrors : _allErrors = createAjvInstance(Ajv3, true);
|
|
50121
50121
|
return _allErrors;
|
|
50122
50122
|
}
|
|
50123
50123
|
};
|
|
@@ -50764,10 +50764,34 @@ var WorkflowSchema = z11.object({
|
|
|
50764
50764
|
var ComponentsSchema = z12.object({
|
|
50765
50765
|
schemas: z12.record(z12.string(), z12.record(z12.string(), z12.any())).default({})
|
|
50766
50766
|
}).passthrough();
|
|
50767
|
+
var SCOPE_NODE_TYPES = [
|
|
50768
|
+
"root",
|
|
50769
|
+
"system",
|
|
50770
|
+
"agent",
|
|
50771
|
+
"task",
|
|
50772
|
+
"execution_step",
|
|
50773
|
+
"artifact",
|
|
50774
|
+
"tool",
|
|
50775
|
+
"tool_command",
|
|
50776
|
+
"validation",
|
|
50777
|
+
"handoff_type",
|
|
50778
|
+
"workflow",
|
|
50779
|
+
"workflow_step",
|
|
50780
|
+
"policy",
|
|
50781
|
+
"guardrail",
|
|
50782
|
+
"guardrail_policy",
|
|
50783
|
+
"rule",
|
|
50784
|
+
"escalation_criterion",
|
|
50785
|
+
"prerequisite"
|
|
50786
|
+
];
|
|
50787
|
+
var ScopeNodeTypeSchema = z12.enum(SCOPE_NODE_TYPES);
|
|
50767
50788
|
var XExtensionDeclSchema = z12.object({
|
|
50768
50789
|
type: z12.string(),
|
|
50769
50790
|
items: z12.string().optional(),
|
|
50770
|
-
description: z12.string().optional()
|
|
50791
|
+
description: z12.string().optional(),
|
|
50792
|
+
scope: z12.array(ScopeNodeTypeSchema).optional(),
|
|
50793
|
+
schema: z12.record(z12.string(), z12.any()).optional(),
|
|
50794
|
+
required: z12.boolean().default(false)
|
|
50771
50795
|
});
|
|
50772
50796
|
var DslSchema = z12.object({
|
|
50773
50797
|
version: z12.literal(1),
|
|
@@ -50784,7 +50808,8 @@ var DslSchema = z12.object({
|
|
|
50784
50808
|
guardrails: z12.record(z12.string(), GuardrailSchema).default({}),
|
|
50785
50809
|
guardrail_policies: z12.record(z12.string(), GuardrailPolicySchema).default({}),
|
|
50786
50810
|
components: ComponentsSchema.default({ schemas: {} }),
|
|
50787
|
-
|
|
50811
|
+
extensions: z12.record(z12.string(), XExtensionDeclSchema).default({}),
|
|
50812
|
+
extensions_strict: z12.boolean().default(false)
|
|
50788
50813
|
}).passthrough();
|
|
50789
50814
|
|
|
50790
50815
|
// src/schema/json-schema-utils.ts
|
|
@@ -51541,7 +51566,8 @@ var MERGE_SECTIONS = [
|
|
|
51541
51566
|
"policies",
|
|
51542
51567
|
"guardrails",
|
|
51543
51568
|
"guardrail_policies",
|
|
51544
|
-
"components"
|
|
51569
|
+
"components",
|
|
51570
|
+
"extensions"
|
|
51545
51571
|
];
|
|
51546
51572
|
function mergeDsl(base, project) {
|
|
51547
51573
|
const hasExtends = typeof project["extends"] === "string";
|
|
@@ -51812,6 +51838,7 @@ var resolveCommand = new Command("resolve").description("Resolve DSL (load + mer
|
|
|
51812
51838
|
import { Command as Command2 } from "commander";
|
|
51813
51839
|
|
|
51814
51840
|
// src/validator/schema-validator.ts
|
|
51841
|
+
import Ajv from "ajv";
|
|
51815
51842
|
import { z as z15 } from "zod";
|
|
51816
51843
|
function unwrap(schema) {
|
|
51817
51844
|
if (schema instanceof z15.ZodOptional) return unwrap(schema.unwrap());
|
|
@@ -51873,14 +51900,14 @@ function checkCustomPropsRecursive(data, schema, path) {
|
|
|
51873
51900
|
}
|
|
51874
51901
|
return [];
|
|
51875
51902
|
}
|
|
51876
|
-
function
|
|
51877
|
-
const extensions = data["
|
|
51903
|
+
function checkExtensionsKeys(data) {
|
|
51904
|
+
const extensions = data["extensions"];
|
|
51878
51905
|
if (typeof extensions !== "object" || extensions === null) return [];
|
|
51879
51906
|
const diagnostics = [];
|
|
51880
51907
|
for (const key of Object.keys(extensions)) {
|
|
51881
51908
|
if (!key.startsWith("x-")) {
|
|
51882
51909
|
diagnostics.push({
|
|
51883
|
-
path: `
|
|
51910
|
+
path: `extensions.${key}`,
|
|
51884
51911
|
message: `Extension key "${key}" must start with "x-" prefix.`,
|
|
51885
51912
|
code: "x-extension-key-prefix"
|
|
51886
51913
|
});
|
|
@@ -51914,29 +51941,634 @@ function checkDecisionStepRoutingKey(data) {
|
|
|
51914
51941
|
}
|
|
51915
51942
|
return diagnostics;
|
|
51916
51943
|
}
|
|
51917
|
-
function
|
|
51918
|
-
|
|
51919
|
-
|
|
51920
|
-
|
|
51921
|
-
|
|
51922
|
-
|
|
51923
|
-
|
|
51924
|
-
|
|
51925
|
-
|
|
51944
|
+
function isRecord4(v2) {
|
|
51945
|
+
return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
|
|
51946
|
+
}
|
|
51947
|
+
function* enumerateEntitiesByType(data, nodeType) {
|
|
51948
|
+
switch (nodeType) {
|
|
51949
|
+
case "root":
|
|
51950
|
+
yield { path: "", obj: data };
|
|
51951
|
+
return;
|
|
51952
|
+
case "system": {
|
|
51953
|
+
const sys = data["system"];
|
|
51954
|
+
if (isRecord4(sys)) yield { path: "system", obj: sys };
|
|
51955
|
+
return;
|
|
51956
|
+
}
|
|
51957
|
+
case "agent": {
|
|
51958
|
+
const agents = data["agents"];
|
|
51959
|
+
if (!isRecord4(agents)) return;
|
|
51960
|
+
for (const [id, a3] of Object.entries(agents)) {
|
|
51961
|
+
if (isRecord4(a3)) yield { path: `agents.${id}`, obj: a3 };
|
|
51962
|
+
}
|
|
51963
|
+
return;
|
|
51964
|
+
}
|
|
51965
|
+
case "rule": {
|
|
51966
|
+
const agents = data["agents"];
|
|
51967
|
+
if (!isRecord4(agents)) return;
|
|
51968
|
+
for (const [aid, a3] of Object.entries(agents)) {
|
|
51969
|
+
if (!isRecord4(a3)) continue;
|
|
51970
|
+
const rules = a3["rules"];
|
|
51971
|
+
if (!Array.isArray(rules)) continue;
|
|
51972
|
+
for (let i3 = 0; i3 < rules.length; i3++) {
|
|
51973
|
+
const r3 = rules[i3];
|
|
51974
|
+
if (isRecord4(r3)) yield { path: `agents.${aid}.rules[${i3}]`, obj: r3 };
|
|
51975
|
+
}
|
|
51976
|
+
}
|
|
51977
|
+
return;
|
|
51978
|
+
}
|
|
51979
|
+
case "escalation_criterion": {
|
|
51980
|
+
const agents = data["agents"];
|
|
51981
|
+
if (!isRecord4(agents)) return;
|
|
51982
|
+
for (const [aid, a3] of Object.entries(agents)) {
|
|
51983
|
+
if (!isRecord4(a3)) continue;
|
|
51984
|
+
const esc = a3["escalation_criteria"];
|
|
51985
|
+
if (!Array.isArray(esc)) continue;
|
|
51986
|
+
for (let i3 = 0; i3 < esc.length; i3++) {
|
|
51987
|
+
const e3 = esc[i3];
|
|
51988
|
+
if (isRecord4(e3)) {
|
|
51989
|
+
yield {
|
|
51990
|
+
path: `agents.${aid}.escalation_criteria[${i3}]`,
|
|
51991
|
+
obj: e3
|
|
51992
|
+
};
|
|
51993
|
+
}
|
|
51994
|
+
}
|
|
51995
|
+
}
|
|
51996
|
+
return;
|
|
51997
|
+
}
|
|
51998
|
+
case "prerequisite": {
|
|
51999
|
+
const agents = data["agents"];
|
|
52000
|
+
if (!isRecord4(agents)) return;
|
|
52001
|
+
for (const [aid, a3] of Object.entries(agents)) {
|
|
52002
|
+
if (!isRecord4(a3)) continue;
|
|
52003
|
+
const pre = a3["prerequisites"];
|
|
52004
|
+
if (!Array.isArray(pre)) continue;
|
|
52005
|
+
for (let i3 = 0; i3 < pre.length; i3++) {
|
|
52006
|
+
const p2 = pre[i3];
|
|
52007
|
+
if (isRecord4(p2)) {
|
|
52008
|
+
yield { path: `agents.${aid}.prerequisites[${i3}]`, obj: p2 };
|
|
52009
|
+
}
|
|
52010
|
+
}
|
|
52011
|
+
}
|
|
52012
|
+
return;
|
|
52013
|
+
}
|
|
52014
|
+
case "task": {
|
|
52015
|
+
const tasks = data["tasks"];
|
|
52016
|
+
if (!isRecord4(tasks)) return;
|
|
52017
|
+
for (const [id, t3] of Object.entries(tasks)) {
|
|
52018
|
+
if (isRecord4(t3)) yield { path: `tasks.${id}`, obj: t3 };
|
|
52019
|
+
}
|
|
52020
|
+
return;
|
|
52021
|
+
}
|
|
52022
|
+
case "execution_step": {
|
|
52023
|
+
const tasks = data["tasks"];
|
|
52024
|
+
if (!isRecord4(tasks)) return;
|
|
52025
|
+
for (const [tid, t3] of Object.entries(tasks)) {
|
|
52026
|
+
if (!isRecord4(t3)) continue;
|
|
52027
|
+
const steps = t3["execution_steps"];
|
|
52028
|
+
if (!Array.isArray(steps)) continue;
|
|
52029
|
+
for (let i3 = 0; i3 < steps.length; i3++) {
|
|
52030
|
+
const s2 = steps[i3];
|
|
52031
|
+
if (isRecord4(s2)) {
|
|
52032
|
+
yield {
|
|
52033
|
+
path: `tasks.${tid}.execution_steps[${i3}]`,
|
|
52034
|
+
obj: s2
|
|
52035
|
+
};
|
|
52036
|
+
}
|
|
52037
|
+
}
|
|
52038
|
+
}
|
|
52039
|
+
return;
|
|
52040
|
+
}
|
|
52041
|
+
case "artifact": {
|
|
52042
|
+
const arts = data["artifacts"];
|
|
52043
|
+
if (!isRecord4(arts)) return;
|
|
52044
|
+
for (const [id, a3] of Object.entries(arts)) {
|
|
52045
|
+
if (isRecord4(a3)) yield { path: `artifacts.${id}`, obj: a3 };
|
|
52046
|
+
}
|
|
52047
|
+
return;
|
|
52048
|
+
}
|
|
52049
|
+
case "tool": {
|
|
52050
|
+
const tools = data["tools"];
|
|
52051
|
+
if (!isRecord4(tools)) return;
|
|
52052
|
+
for (const [id, t3] of Object.entries(tools)) {
|
|
52053
|
+
if (isRecord4(t3)) yield { path: `tools.${id}`, obj: t3 };
|
|
52054
|
+
}
|
|
52055
|
+
return;
|
|
52056
|
+
}
|
|
52057
|
+
case "tool_command": {
|
|
52058
|
+
const tools = data["tools"];
|
|
52059
|
+
if (!isRecord4(tools)) return;
|
|
52060
|
+
for (const [tid, t3] of Object.entries(tools)) {
|
|
52061
|
+
if (!isRecord4(t3)) continue;
|
|
52062
|
+
const cmds = t3["commands"];
|
|
52063
|
+
if (!Array.isArray(cmds)) continue;
|
|
52064
|
+
for (let i3 = 0; i3 < cmds.length; i3++) {
|
|
52065
|
+
const c2 = cmds[i3];
|
|
52066
|
+
if (isRecord4(c2)) {
|
|
52067
|
+
yield { path: `tools.${tid}.commands[${i3}]`, obj: c2 };
|
|
52068
|
+
}
|
|
52069
|
+
}
|
|
52070
|
+
}
|
|
52071
|
+
return;
|
|
52072
|
+
}
|
|
52073
|
+
case "validation": {
|
|
52074
|
+
const vals = data["validations"];
|
|
52075
|
+
if (!isRecord4(vals)) return;
|
|
52076
|
+
for (const [id, v2] of Object.entries(vals)) {
|
|
52077
|
+
if (isRecord4(v2)) yield { path: `validations.${id}`, obj: v2 };
|
|
52078
|
+
}
|
|
52079
|
+
return;
|
|
52080
|
+
}
|
|
52081
|
+
case "handoff_type": {
|
|
52082
|
+
const ht = data["handoff_types"];
|
|
52083
|
+
if (!isRecord4(ht)) return;
|
|
52084
|
+
for (const [id, h2] of Object.entries(ht)) {
|
|
52085
|
+
if (isRecord4(h2)) yield { path: `handoff_types.${id}`, obj: h2 };
|
|
52086
|
+
}
|
|
52087
|
+
return;
|
|
52088
|
+
}
|
|
52089
|
+
case "workflow": {
|
|
52090
|
+
const wf = data["workflow"];
|
|
52091
|
+
if (!isRecord4(wf)) return;
|
|
52092
|
+
for (const [id, w2] of Object.entries(wf)) {
|
|
52093
|
+
if (isRecord4(w2)) yield { path: `workflow.${id}`, obj: w2 };
|
|
52094
|
+
}
|
|
52095
|
+
return;
|
|
52096
|
+
}
|
|
52097
|
+
case "workflow_step": {
|
|
52098
|
+
const wf = data["workflow"];
|
|
52099
|
+
if (!isRecord4(wf)) return;
|
|
52100
|
+
for (const [wid, w2] of Object.entries(wf)) {
|
|
52101
|
+
if (!isRecord4(w2)) continue;
|
|
52102
|
+
const steps = w2["steps"];
|
|
52103
|
+
if (!Array.isArray(steps)) continue;
|
|
52104
|
+
for (let i3 = 0; i3 < steps.length; i3++) {
|
|
52105
|
+
const s2 = steps[i3];
|
|
52106
|
+
if (isRecord4(s2)) {
|
|
52107
|
+
yield { path: `workflow.${wid}.steps[${i3}]`, obj: s2 };
|
|
52108
|
+
}
|
|
52109
|
+
}
|
|
52110
|
+
}
|
|
52111
|
+
return;
|
|
52112
|
+
}
|
|
52113
|
+
case "policy": {
|
|
52114
|
+
const pol = data["policies"];
|
|
52115
|
+
if (!isRecord4(pol)) return;
|
|
52116
|
+
for (const [id, p2] of Object.entries(pol)) {
|
|
52117
|
+
if (isRecord4(p2)) yield { path: `policies.${id}`, obj: p2 };
|
|
52118
|
+
}
|
|
52119
|
+
return;
|
|
52120
|
+
}
|
|
52121
|
+
case "guardrail": {
|
|
52122
|
+
const gr = data["guardrails"];
|
|
52123
|
+
if (!isRecord4(gr)) return;
|
|
52124
|
+
for (const [id, g2] of Object.entries(gr)) {
|
|
52125
|
+
if (isRecord4(g2)) yield { path: `guardrails.${id}`, obj: g2 };
|
|
52126
|
+
}
|
|
52127
|
+
return;
|
|
52128
|
+
}
|
|
52129
|
+
case "guardrail_policy": {
|
|
52130
|
+
const gp = data["guardrail_policies"];
|
|
52131
|
+
if (!isRecord4(gp)) return;
|
|
52132
|
+
for (const [id, p2] of Object.entries(gp)) {
|
|
52133
|
+
if (isRecord4(p2)) yield { path: `guardrail_policies.${id}`, obj: p2 };
|
|
52134
|
+
}
|
|
52135
|
+
return;
|
|
52136
|
+
}
|
|
52137
|
+
default:
|
|
52138
|
+
return;
|
|
52139
|
+
}
|
|
52140
|
+
}
|
|
52141
|
+
function validateDeclaredExtension(parentPath, nodeType, key, val, declMap, diagnostics, ajvInstance, strict) {
|
|
52142
|
+
const path = parentPath ? `${parentPath}.${key}` : key;
|
|
52143
|
+
const decl = declMap[key];
|
|
52144
|
+
if (decl === void 0) {
|
|
52145
|
+
diagnostics.push({
|
|
52146
|
+
path,
|
|
52147
|
+
message: `Extension "${key}" is not declared in extensions.`,
|
|
52148
|
+
code: "undeclared-extension",
|
|
52149
|
+
...!strict ? { severity: "warning" } : {}
|
|
52150
|
+
});
|
|
52151
|
+
return;
|
|
52152
|
+
}
|
|
52153
|
+
const scope = decl.scope;
|
|
52154
|
+
if (scope && scope.length > 0 && !scope.includes(nodeType)) {
|
|
52155
|
+
diagnostics.push({
|
|
52156
|
+
path,
|
|
52157
|
+
message: `Extension "${key}" is not allowed on ${nodeType} (declared scope: ${scope.join(", ")}).`,
|
|
52158
|
+
code: "extension-scope-mismatch"
|
|
52159
|
+
});
|
|
52160
|
+
return;
|
|
52161
|
+
}
|
|
52162
|
+
if (decl.schema && typeof decl.schema === "object" && decl.schema !== null && Object.keys(decl.schema).length > 0) {
|
|
52163
|
+
try {
|
|
52164
|
+
const validate = ajvInstance.compile(decl.schema);
|
|
52165
|
+
if (!validate(val)) {
|
|
52166
|
+
diagnostics.push({
|
|
52167
|
+
path,
|
|
52168
|
+
message: `Extension "${key}" value does not match declared schema: ${ajvInstance.errorsText(validate.errors)}`,
|
|
52169
|
+
code: "extension-schema-violation"
|
|
52170
|
+
});
|
|
52171
|
+
}
|
|
52172
|
+
} catch (e3) {
|
|
52173
|
+
diagnostics.push({
|
|
52174
|
+
path,
|
|
52175
|
+
message: `Extension "${key}" has invalid JSON Schema in declaration: ${e3 instanceof Error ? e3.message : String(e3)}`,
|
|
52176
|
+
code: "extension-schema-violation"
|
|
52177
|
+
});
|
|
52178
|
+
}
|
|
52179
|
+
}
|
|
52180
|
+
}
|
|
52181
|
+
function walkExtensionNodes(value, path, nodeType, declMap, diagnostics, ajvInstance, strict) {
|
|
52182
|
+
if (!isRecord4(value)) return;
|
|
52183
|
+
const obj = value;
|
|
52184
|
+
for (const key of Object.keys(obj)) {
|
|
52185
|
+
if (key === "extensions" || key === "extensions_strict" || key === "x-extensions" || key === "x-extensions-strict") {
|
|
52186
|
+
continue;
|
|
52187
|
+
}
|
|
52188
|
+
if (key.startsWith("x-")) {
|
|
52189
|
+
validateDeclaredExtension(
|
|
52190
|
+
path,
|
|
52191
|
+
nodeType,
|
|
52192
|
+
key,
|
|
52193
|
+
obj[key],
|
|
52194
|
+
declMap,
|
|
52195
|
+
diagnostics,
|
|
52196
|
+
ajvInstance,
|
|
52197
|
+
strict
|
|
52198
|
+
);
|
|
52199
|
+
}
|
|
52200
|
+
}
|
|
52201
|
+
switch (nodeType) {
|
|
52202
|
+
case "root": {
|
|
52203
|
+
const sys = obj["system"];
|
|
52204
|
+
if (isRecord4(sys)) {
|
|
52205
|
+
walkExtensionNodes(
|
|
52206
|
+
sys,
|
|
52207
|
+
"system",
|
|
52208
|
+
"system",
|
|
52209
|
+
declMap,
|
|
52210
|
+
diagnostics,
|
|
52211
|
+
ajvInstance,
|
|
52212
|
+
strict
|
|
52213
|
+
);
|
|
52214
|
+
}
|
|
52215
|
+
const agents = obj["agents"];
|
|
52216
|
+
if (isRecord4(agents)) {
|
|
52217
|
+
for (const [id, a3] of Object.entries(agents)) {
|
|
52218
|
+
if (isRecord4(a3)) {
|
|
52219
|
+
walkExtensionNodes(
|
|
52220
|
+
a3,
|
|
52221
|
+
`agents.${id}`,
|
|
52222
|
+
"agent",
|
|
52223
|
+
declMap,
|
|
52224
|
+
diagnostics,
|
|
52225
|
+
ajvInstance,
|
|
52226
|
+
strict
|
|
52227
|
+
);
|
|
52228
|
+
}
|
|
52229
|
+
}
|
|
52230
|
+
}
|
|
52231
|
+
const tasks = obj["tasks"];
|
|
52232
|
+
if (isRecord4(tasks)) {
|
|
52233
|
+
for (const [id, t3] of Object.entries(tasks)) {
|
|
52234
|
+
if (isRecord4(t3)) {
|
|
52235
|
+
walkExtensionNodes(
|
|
52236
|
+
t3,
|
|
52237
|
+
`tasks.${id}`,
|
|
52238
|
+
"task",
|
|
52239
|
+
declMap,
|
|
52240
|
+
diagnostics,
|
|
52241
|
+
ajvInstance,
|
|
52242
|
+
strict
|
|
52243
|
+
);
|
|
52244
|
+
}
|
|
52245
|
+
}
|
|
52246
|
+
}
|
|
52247
|
+
const artifacts = obj["artifacts"];
|
|
52248
|
+
if (isRecord4(artifacts)) {
|
|
52249
|
+
for (const [id, a3] of Object.entries(artifacts)) {
|
|
52250
|
+
if (isRecord4(a3)) {
|
|
52251
|
+
walkExtensionNodes(
|
|
52252
|
+
a3,
|
|
52253
|
+
`artifacts.${id}`,
|
|
52254
|
+
"artifact",
|
|
52255
|
+
declMap,
|
|
52256
|
+
diagnostics,
|
|
52257
|
+
ajvInstance,
|
|
52258
|
+
strict
|
|
52259
|
+
);
|
|
52260
|
+
}
|
|
52261
|
+
}
|
|
52262
|
+
}
|
|
52263
|
+
const tools = obj["tools"];
|
|
52264
|
+
if (isRecord4(tools)) {
|
|
52265
|
+
for (const [id, t3] of Object.entries(tools)) {
|
|
52266
|
+
if (isRecord4(t3)) {
|
|
52267
|
+
walkExtensionNodes(
|
|
52268
|
+
t3,
|
|
52269
|
+
`tools.${id}`,
|
|
52270
|
+
"tool",
|
|
52271
|
+
declMap,
|
|
52272
|
+
diagnostics,
|
|
52273
|
+
ajvInstance,
|
|
52274
|
+
strict
|
|
52275
|
+
);
|
|
52276
|
+
}
|
|
52277
|
+
}
|
|
52278
|
+
}
|
|
52279
|
+
const validations = obj["validations"];
|
|
52280
|
+
if (isRecord4(validations)) {
|
|
52281
|
+
for (const [id, v2] of Object.entries(validations)) {
|
|
52282
|
+
if (isRecord4(v2)) {
|
|
52283
|
+
walkExtensionNodes(
|
|
52284
|
+
v2,
|
|
52285
|
+
`validations.${id}`,
|
|
52286
|
+
"validation",
|
|
52287
|
+
declMap,
|
|
52288
|
+
diagnostics,
|
|
52289
|
+
ajvInstance,
|
|
52290
|
+
strict
|
|
52291
|
+
);
|
|
52292
|
+
}
|
|
52293
|
+
}
|
|
52294
|
+
}
|
|
52295
|
+
const handoffTypes = obj["handoff_types"];
|
|
52296
|
+
if (isRecord4(handoffTypes)) {
|
|
52297
|
+
for (const [id, h2] of Object.entries(handoffTypes)) {
|
|
52298
|
+
if (isRecord4(h2)) {
|
|
52299
|
+
walkExtensionNodes(
|
|
52300
|
+
h2,
|
|
52301
|
+
`handoff_types.${id}`,
|
|
52302
|
+
"handoff_type",
|
|
52303
|
+
declMap,
|
|
52304
|
+
diagnostics,
|
|
52305
|
+
ajvInstance,
|
|
52306
|
+
strict
|
|
52307
|
+
);
|
|
52308
|
+
}
|
|
52309
|
+
}
|
|
52310
|
+
}
|
|
52311
|
+
const workflow = obj["workflow"];
|
|
52312
|
+
if (isRecord4(workflow)) {
|
|
52313
|
+
for (const [id, w2] of Object.entries(workflow)) {
|
|
52314
|
+
if (isRecord4(w2)) {
|
|
52315
|
+
walkExtensionNodes(
|
|
52316
|
+
w2,
|
|
52317
|
+
`workflow.${id}`,
|
|
52318
|
+
"workflow",
|
|
52319
|
+
declMap,
|
|
52320
|
+
diagnostics,
|
|
52321
|
+
ajvInstance,
|
|
52322
|
+
strict
|
|
52323
|
+
);
|
|
52324
|
+
}
|
|
52325
|
+
}
|
|
52326
|
+
}
|
|
52327
|
+
const policies = obj["policies"];
|
|
52328
|
+
if (isRecord4(policies)) {
|
|
52329
|
+
for (const [id, p2] of Object.entries(policies)) {
|
|
52330
|
+
if (isRecord4(p2)) {
|
|
52331
|
+
walkExtensionNodes(
|
|
52332
|
+
p2,
|
|
52333
|
+
`policies.${id}`,
|
|
52334
|
+
"policy",
|
|
52335
|
+
declMap,
|
|
52336
|
+
diagnostics,
|
|
52337
|
+
ajvInstance,
|
|
52338
|
+
strict
|
|
52339
|
+
);
|
|
52340
|
+
}
|
|
52341
|
+
}
|
|
52342
|
+
}
|
|
52343
|
+
const guardrails = obj["guardrails"];
|
|
52344
|
+
if (isRecord4(guardrails)) {
|
|
52345
|
+
for (const [id, g2] of Object.entries(guardrails)) {
|
|
52346
|
+
if (isRecord4(g2)) {
|
|
52347
|
+
walkExtensionNodes(
|
|
52348
|
+
g2,
|
|
52349
|
+
`guardrails.${id}`,
|
|
52350
|
+
"guardrail",
|
|
52351
|
+
declMap,
|
|
52352
|
+
diagnostics,
|
|
52353
|
+
ajvInstance,
|
|
52354
|
+
strict
|
|
52355
|
+
);
|
|
52356
|
+
}
|
|
52357
|
+
}
|
|
52358
|
+
}
|
|
52359
|
+
const guardrailPolicies = obj["guardrail_policies"];
|
|
52360
|
+
if (isRecord4(guardrailPolicies)) {
|
|
52361
|
+
for (const [id, p2] of Object.entries(guardrailPolicies)) {
|
|
52362
|
+
if (isRecord4(p2)) {
|
|
52363
|
+
walkExtensionNodes(
|
|
52364
|
+
p2,
|
|
52365
|
+
`guardrail_policies.${id}`,
|
|
52366
|
+
"guardrail_policy",
|
|
52367
|
+
declMap,
|
|
52368
|
+
diagnostics,
|
|
52369
|
+
ajvInstance,
|
|
52370
|
+
strict
|
|
52371
|
+
);
|
|
52372
|
+
}
|
|
52373
|
+
}
|
|
52374
|
+
}
|
|
52375
|
+
break;
|
|
52376
|
+
}
|
|
52377
|
+
case "agent": {
|
|
52378
|
+
const rules = obj["rules"];
|
|
52379
|
+
if (Array.isArray(rules)) {
|
|
52380
|
+
for (let i3 = 0; i3 < rules.length; i3++) {
|
|
52381
|
+
const r3 = rules[i3];
|
|
52382
|
+
if (isRecord4(r3)) {
|
|
52383
|
+
walkExtensionNodes(
|
|
52384
|
+
r3,
|
|
52385
|
+
`${path}.rules[${i3}]`,
|
|
52386
|
+
"rule",
|
|
52387
|
+
declMap,
|
|
52388
|
+
diagnostics,
|
|
52389
|
+
ajvInstance,
|
|
52390
|
+
strict
|
|
52391
|
+
);
|
|
52392
|
+
}
|
|
52393
|
+
}
|
|
52394
|
+
}
|
|
52395
|
+
const esc = obj["escalation_criteria"];
|
|
52396
|
+
if (Array.isArray(esc)) {
|
|
52397
|
+
for (let i3 = 0; i3 < esc.length; i3++) {
|
|
52398
|
+
const e3 = esc[i3];
|
|
52399
|
+
if (isRecord4(e3)) {
|
|
52400
|
+
walkExtensionNodes(
|
|
52401
|
+
e3,
|
|
52402
|
+
`${path}.escalation_criteria[${i3}]`,
|
|
52403
|
+
"escalation_criterion",
|
|
52404
|
+
declMap,
|
|
52405
|
+
diagnostics,
|
|
52406
|
+
ajvInstance,
|
|
52407
|
+
strict
|
|
52408
|
+
);
|
|
52409
|
+
}
|
|
52410
|
+
}
|
|
52411
|
+
}
|
|
52412
|
+
const pre = obj["prerequisites"];
|
|
52413
|
+
if (Array.isArray(pre)) {
|
|
52414
|
+
for (let i3 = 0; i3 < pre.length; i3++) {
|
|
52415
|
+
const p2 = pre[i3];
|
|
52416
|
+
if (isRecord4(p2)) {
|
|
52417
|
+
walkExtensionNodes(
|
|
52418
|
+
p2,
|
|
52419
|
+
`${path}.prerequisites[${i3}]`,
|
|
52420
|
+
"prerequisite",
|
|
52421
|
+
declMap,
|
|
52422
|
+
diagnostics,
|
|
52423
|
+
ajvInstance,
|
|
52424
|
+
strict
|
|
52425
|
+
);
|
|
52426
|
+
}
|
|
52427
|
+
}
|
|
52428
|
+
}
|
|
52429
|
+
break;
|
|
52430
|
+
}
|
|
52431
|
+
case "task": {
|
|
52432
|
+
const steps = obj["execution_steps"];
|
|
52433
|
+
if (Array.isArray(steps)) {
|
|
52434
|
+
for (let i3 = 0; i3 < steps.length; i3++) {
|
|
52435
|
+
const s2 = steps[i3];
|
|
52436
|
+
if (isRecord4(s2)) {
|
|
52437
|
+
walkExtensionNodes(
|
|
52438
|
+
s2,
|
|
52439
|
+
`${path}.execution_steps[${i3}]`,
|
|
52440
|
+
"execution_step",
|
|
52441
|
+
declMap,
|
|
52442
|
+
diagnostics,
|
|
52443
|
+
ajvInstance,
|
|
52444
|
+
strict
|
|
52445
|
+
);
|
|
52446
|
+
}
|
|
52447
|
+
}
|
|
52448
|
+
}
|
|
52449
|
+
break;
|
|
52450
|
+
}
|
|
52451
|
+
case "tool": {
|
|
52452
|
+
const cmds = obj["commands"];
|
|
52453
|
+
if (Array.isArray(cmds)) {
|
|
52454
|
+
for (let i3 = 0; i3 < cmds.length; i3++) {
|
|
52455
|
+
const c2 = cmds[i3];
|
|
52456
|
+
if (isRecord4(c2)) {
|
|
52457
|
+
walkExtensionNodes(
|
|
52458
|
+
c2,
|
|
52459
|
+
`${path}.commands[${i3}]`,
|
|
52460
|
+
"tool_command",
|
|
52461
|
+
declMap,
|
|
52462
|
+
diagnostics,
|
|
52463
|
+
ajvInstance,
|
|
52464
|
+
strict
|
|
52465
|
+
);
|
|
52466
|
+
}
|
|
52467
|
+
}
|
|
52468
|
+
}
|
|
52469
|
+
break;
|
|
52470
|
+
}
|
|
52471
|
+
case "workflow": {
|
|
52472
|
+
const steps = obj["steps"];
|
|
52473
|
+
if (Array.isArray(steps)) {
|
|
52474
|
+
for (let i3 = 0; i3 < steps.length; i3++) {
|
|
52475
|
+
const s2 = steps[i3];
|
|
52476
|
+
if (isRecord4(s2)) {
|
|
52477
|
+
walkExtensionNodes(
|
|
52478
|
+
s2,
|
|
52479
|
+
`${path}.steps[${i3}]`,
|
|
52480
|
+
"workflow_step",
|
|
52481
|
+
declMap,
|
|
52482
|
+
diagnostics,
|
|
52483
|
+
ajvInstance,
|
|
52484
|
+
strict
|
|
52485
|
+
);
|
|
52486
|
+
}
|
|
52487
|
+
}
|
|
52488
|
+
}
|
|
52489
|
+
break;
|
|
52490
|
+
}
|
|
52491
|
+
default:
|
|
52492
|
+
break;
|
|
51926
52493
|
}
|
|
51927
|
-
|
|
51928
|
-
|
|
51929
|
-
|
|
52494
|
+
}
|
|
52495
|
+
function checkExtensionValidation(data) {
|
|
52496
|
+
const strict = data["extensions_strict"] === true;
|
|
52497
|
+
const raw = data["extensions"];
|
|
52498
|
+
let declMap;
|
|
52499
|
+
if (!isRecord4(raw) || Object.keys(raw).length === 0) {
|
|
52500
|
+
if (!strict) return [];
|
|
52501
|
+
declMap = {};
|
|
52502
|
+
} else {
|
|
52503
|
+
declMap = raw;
|
|
52504
|
+
}
|
|
52505
|
+
const diagnostics = [];
|
|
52506
|
+
const ajvInstance = new Ajv({ allErrors: true, strict: false });
|
|
52507
|
+
walkExtensionNodes(data, "", "root", declMap, diagnostics, ajvInstance, strict);
|
|
52508
|
+
for (const [extKey, decl] of Object.entries(declMap)) {
|
|
52509
|
+
if (!decl.required) continue;
|
|
52510
|
+
const applicableTypes = decl.scope && decl.scope.length > 0 ? decl.scope : [...SCOPE_NODE_TYPES];
|
|
52511
|
+
for (const t3 of applicableTypes) {
|
|
52512
|
+
for (const { path, obj } of enumerateEntitiesByType(data, t3)) {
|
|
52513
|
+
if (!(extKey in obj)) {
|
|
52514
|
+
diagnostics.push({
|
|
52515
|
+
path,
|
|
52516
|
+
message: `Required extension "${extKey}" is missing on ${t3}.`,
|
|
52517
|
+
code: "extension-required-missing"
|
|
52518
|
+
});
|
|
52519
|
+
}
|
|
52520
|
+
}
|
|
52521
|
+
}
|
|
51930
52522
|
}
|
|
51931
|
-
|
|
51932
|
-
|
|
51933
|
-
|
|
52523
|
+
return diagnostics;
|
|
52524
|
+
}
|
|
52525
|
+
function hasBlockingDiagnostic(diagnostics) {
|
|
52526
|
+
return diagnostics.some((d2) => d2.severity !== "warning");
|
|
52527
|
+
}
|
|
52528
|
+
function validateSchema(data) {
|
|
52529
|
+
const deprecationWarnings = [];
|
|
52530
|
+
if ("x-extensions" in data && !("extensions" in data)) {
|
|
52531
|
+
data["extensions"] = data["x-extensions"];
|
|
52532
|
+
deprecationWarnings.push({
|
|
52533
|
+
path: "x-extensions",
|
|
52534
|
+
message: '"x-extensions" is deprecated. Use "extensions" instead.',
|
|
52535
|
+
code: "deprecated-property",
|
|
52536
|
+
severity: "warning"
|
|
52537
|
+
});
|
|
51934
52538
|
}
|
|
51935
|
-
|
|
51936
|
-
|
|
51937
|
-
|
|
52539
|
+
if ("x-extensions-strict" in data && !("extensions_strict" in data)) {
|
|
52540
|
+
data["extensions_strict"] = data["x-extensions-strict"];
|
|
52541
|
+
deprecationWarnings.push({
|
|
52542
|
+
path: "x-extensions-strict",
|
|
52543
|
+
message: '"x-extensions-strict" is deprecated. Use "extensions_strict" instead.',
|
|
52544
|
+
code: "deprecated-property",
|
|
52545
|
+
severity: "warning"
|
|
52546
|
+
});
|
|
51938
52547
|
}
|
|
51939
|
-
|
|
52548
|
+
const result = DslSchema.safeParse(data);
|
|
52549
|
+
if (!result.success) {
|
|
52550
|
+
const diagnostics2 = [
|
|
52551
|
+
...deprecationWarnings,
|
|
52552
|
+
...result.error.issues.map((issue) => ({
|
|
52553
|
+
path: issue.path.join("."),
|
|
52554
|
+
message: issue.message,
|
|
52555
|
+
code: "schema-validation"
|
|
52556
|
+
}))
|
|
52557
|
+
];
|
|
52558
|
+
return { success: false, diagnostics: diagnostics2 };
|
|
52559
|
+
}
|
|
52560
|
+
const diagnostics = [
|
|
52561
|
+
...deprecationWarnings,
|
|
52562
|
+
...checkCustomPropsRecursive(data, DslSchema, ""),
|
|
52563
|
+
...checkDecisionStepRoutingKey(data),
|
|
52564
|
+
...checkExtensionsKeys(data),
|
|
52565
|
+
...checkExtensionValidation(data)
|
|
52566
|
+
];
|
|
52567
|
+
return {
|
|
52568
|
+
success: !hasBlockingDiagnostic(diagnostics),
|
|
52569
|
+
data: result.data,
|
|
52570
|
+
diagnostics
|
|
52571
|
+
};
|
|
51940
52572
|
}
|
|
51941
52573
|
|
|
51942
52574
|
// src/validator/reference-resolver.ts
|
|
@@ -52244,8 +52876,8 @@ function checkReferences(dsl) {
|
|
|
52244
52876
|
}
|
|
52245
52877
|
|
|
52246
52878
|
// src/validator/handoff-schema-validator.ts
|
|
52247
|
-
import
|
|
52248
|
-
var ajv = new
|
|
52879
|
+
import Ajv2 from "ajv";
|
|
52880
|
+
var ajv = new Ajv2({ allErrors: true, strict: false });
|
|
52249
52881
|
function validateHandoffSchemas(dsl) {
|
|
52250
52882
|
const diagnostics = [];
|
|
52251
52883
|
for (const [kind, ht] of Object.entries(dsl.handoff_types)) {
|
|
@@ -52280,13 +52912,16 @@ function formatDiagnostics(diagnostics, options) {
|
|
|
52280
52912
|
|
|
52281
52913
|
// src/cli/commands/validate.ts
|
|
52282
52914
|
var DIR_DEFAULT2 = "agent-contracts.yaml";
|
|
52283
|
-
var validateCommand = new Command2("validate").description("Validate DSL against schema and check references").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT2).option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--format <format>", "Output format (text|json)", "text").option("--quiet", "Suppress output on success", false).action(async (dir, opts) => {
|
|
52915
|
+
var validateCommand = new Command2("validate").description("Validate DSL against schema and check references").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT2).option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--format <format>", "Output format (text|json)", "text").option("--quiet", "Suppress output on success", false).option("--strict", "Treat warnings as errors", false).action(async (dir, opts) => {
|
|
52284
52916
|
try {
|
|
52285
52917
|
const config = await loadConfig(opts.config);
|
|
52286
52918
|
const dslPath = resolveDslPath(dir, DIR_DEFAULT2, config);
|
|
52287
52919
|
const resolved = await resolve4(dslPath);
|
|
52288
52920
|
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
52289
52921
|
const schemaResult = validateSchema(data);
|
|
52922
|
+
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
52923
|
+
(d2) => d2.severity === "warning"
|
|
52924
|
+
);
|
|
52290
52925
|
if (!schemaResult.success) {
|
|
52291
52926
|
const output = formatDiagnostics(schemaResult.diagnostics, opts);
|
|
52292
52927
|
if (output) process.stderr.write(output + "\n");
|
|
@@ -52294,13 +52929,18 @@ var validateCommand = new Command2("validate").description("Validate DSL against
|
|
|
52294
52929
|
}
|
|
52295
52930
|
const refDiags = checkReferences(schemaResult.data);
|
|
52296
52931
|
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
52297
|
-
const allDiags = [...refDiags, ...handoffDiags];
|
|
52932
|
+
const allDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
52933
|
+
const hasWarnings = allDiags.some(
|
|
52934
|
+
(d2) => "severity" in d2 && d2.severity === "warning"
|
|
52935
|
+
);
|
|
52298
52936
|
if (allDiags.length > 0) {
|
|
52299
52937
|
const output = formatDiagnostics(allDiags, opts);
|
|
52300
52938
|
if (output) process.stderr.write(output + "\n");
|
|
52301
|
-
|
|
52939
|
+
if (refDiags.length > 0 || handoffDiags.length > 0 || opts.strict && hasWarnings) {
|
|
52940
|
+
process.exit(1);
|
|
52941
|
+
}
|
|
52302
52942
|
}
|
|
52303
|
-
if (!opts.quiet) {
|
|
52943
|
+
if (!opts.quiet && allDiags.length === 0) {
|
|
52304
52944
|
process.stdout.write("Validation passed.\n");
|
|
52305
52945
|
}
|
|
52306
52946
|
} catch (err) {
|
|
@@ -53009,6 +53649,40 @@ var guardrailOrphanedRule = {
|
|
|
53009
53649
|
}
|
|
53010
53650
|
};
|
|
53011
53651
|
|
|
53652
|
+
// src/linter/rules/validation-executor-no-context.ts
|
|
53653
|
+
var validationExecutorNoContextRule = {
|
|
53654
|
+
id: "validation-executor-no-context",
|
|
53655
|
+
description: "Validation executor is not wired so the validation appears in the executor's rendered context",
|
|
53656
|
+
run(dsl) {
|
|
53657
|
+
const diagnostics = [];
|
|
53658
|
+
for (const [validationId, val] of Object.entries(dsl.validations)) {
|
|
53659
|
+
if (val.executor_type === "agent") {
|
|
53660
|
+
const agent = dsl.agents[val.executor];
|
|
53661
|
+
if (!agent) continue;
|
|
53662
|
+
const allowed = new Set(agent.can_perform_validations ?? []);
|
|
53663
|
+
if (!allowed.has(validationId)) {
|
|
53664
|
+
diagnostics.push({
|
|
53665
|
+
ruleId: "validation-executor-no-context",
|
|
53666
|
+
severity: "warning",
|
|
53667
|
+
path: `agents.${val.executor}.can_perform_validations`,
|
|
53668
|
+
message: `Validation "${validationId}" is executed by agent "${val.executor}" but is not listed in can_perform_validations, so it will be missing from that agent's prompt context`
|
|
53669
|
+
});
|
|
53670
|
+
}
|
|
53671
|
+
} else if (val.executor_type === "tool") {
|
|
53672
|
+
if (!dsl.tools[val.executor]) {
|
|
53673
|
+
diagnostics.push({
|
|
53674
|
+
ruleId: "validation-executor-no-context",
|
|
53675
|
+
severity: "warning",
|
|
53676
|
+
path: `validations.${validationId}.executor`,
|
|
53677
|
+
message: `Validation "${validationId}" references tool executor "${val.executor}" which is not defined in tools`
|
|
53678
|
+
});
|
|
53679
|
+
}
|
|
53680
|
+
}
|
|
53681
|
+
}
|
|
53682
|
+
return diagnostics;
|
|
53683
|
+
}
|
|
53684
|
+
};
|
|
53685
|
+
|
|
53012
53686
|
// src/linter/linter.ts
|
|
53013
53687
|
var builtinRules = [
|
|
53014
53688
|
validationCoverageRule,
|
|
@@ -53024,7 +53698,8 @@ var builtinRules = [
|
|
|
53024
53698
|
semanticValidationPhaseCoverageRule,
|
|
53025
53699
|
entityGuardrailUndefinedRule,
|
|
53026
53700
|
entityNoGuardrailsRule,
|
|
53027
|
-
guardrailOrphanedRule
|
|
53701
|
+
guardrailOrphanedRule,
|
|
53702
|
+
validationExecutorNoContextRule
|
|
53028
53703
|
];
|
|
53029
53704
|
function lint(dsl, rules = builtinRules) {
|
|
53030
53705
|
const diagnostics = [];
|
|
@@ -53680,6 +54355,9 @@ var lintCommand = new Command3("lint").description("Run semantic lint rules on r
|
|
|
53680
54355
|
const resolved = await resolve4(dslPath);
|
|
53681
54356
|
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
53682
54357
|
const schemaResult = validateSchema(data);
|
|
54358
|
+
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
54359
|
+
(d2) => d2.severity === "warning"
|
|
54360
|
+
);
|
|
53683
54361
|
if (!schemaResult.success) {
|
|
53684
54362
|
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
53685
54363
|
format: opts.format,
|
|
@@ -53690,7 +54368,7 @@ var lintCommand = new Command3("lint").description("Run semantic lint rules on r
|
|
|
53690
54368
|
}
|
|
53691
54369
|
const tsDiagnostics = lint(schemaResult.data);
|
|
53692
54370
|
const spectralDiagnostics = await spectralLint(schemaResult.data);
|
|
53693
|
-
const diagnostics = [...tsDiagnostics, ...spectralDiagnostics];
|
|
54371
|
+
const diagnostics = [...tsDiagnostics, ...spectralDiagnostics, ...schemaWarnings];
|
|
53694
54372
|
if (diagnostics.length > 0) {
|
|
53695
54373
|
const output = formatDiagnostics(diagnostics, {
|
|
53696
54374
|
format: opts.format,
|
|
@@ -53813,13 +54491,54 @@ function resolveEffectiveGuardrails(dsl, entityType, entityId) {
|
|
|
53813
54491
|
}
|
|
53814
54492
|
return entries;
|
|
53815
54493
|
}
|
|
54494
|
+
function validationToEntityEntry(validationId, validation) {
|
|
54495
|
+
return {
|
|
54496
|
+
validation_id: validationId,
|
|
54497
|
+
kind: validation.kind,
|
|
54498
|
+
target_artifact: validation.target_artifact,
|
|
54499
|
+
executor_type: validation.executor_type,
|
|
54500
|
+
blocking: validation.blocking,
|
|
54501
|
+
produces_evidence: validation.produces_evidence
|
|
54502
|
+
};
|
|
54503
|
+
}
|
|
54504
|
+
function resolveEntityValidations(dsl, entityType, entityId) {
|
|
54505
|
+
if (entityType === "agents") {
|
|
54506
|
+
const agent = dsl.agents[entityId];
|
|
54507
|
+
if (!agent) return [];
|
|
54508
|
+
const entries2 = [];
|
|
54509
|
+
for (const vid of agent.can_perform_validations ?? []) {
|
|
54510
|
+
const v2 = dsl.validations[vid];
|
|
54511
|
+
if (v2) entries2.push(validationToEntityEntry(vid, v2));
|
|
54512
|
+
}
|
|
54513
|
+
return entries2;
|
|
54514
|
+
}
|
|
54515
|
+
if (entityType === "tasks") {
|
|
54516
|
+
const task = dsl.tasks[entityId];
|
|
54517
|
+
if (!task) return [];
|
|
54518
|
+
const entries2 = [];
|
|
54519
|
+
for (const vid of task.validations ?? []) {
|
|
54520
|
+
const v2 = dsl.validations[vid];
|
|
54521
|
+
if (v2) entries2.push(validationToEntityEntry(vid, v2));
|
|
54522
|
+
}
|
|
54523
|
+
return entries2;
|
|
54524
|
+
}
|
|
54525
|
+
const entries = [];
|
|
54526
|
+
for (const [vid, v2] of Object.entries(dsl.validations)) {
|
|
54527
|
+
if (v2.executor_type === "tool" && v2.executor === entityId) {
|
|
54528
|
+
entries.push(validationToEntityEntry(vid, v2));
|
|
54529
|
+
}
|
|
54530
|
+
}
|
|
54531
|
+
entries.sort((a3, b3) => a3.validation_id.localeCompare(b3.validation_id));
|
|
54532
|
+
return entries;
|
|
54533
|
+
}
|
|
53816
54534
|
function buildTaskContext(dsl, taskId) {
|
|
53817
54535
|
const taskDef = dsl.tasks[taskId];
|
|
53818
54536
|
const task = { ...taskDef, id: taskId };
|
|
53819
54537
|
const agentDef = dsl.agents[taskDef.target_agent];
|
|
53820
54538
|
const targetAgent = agentDef ? { ...agentDef, id: taskDef.target_agent } : null;
|
|
53821
54539
|
const relatedGuardrails = resolveEffectiveGuardrails(dsl, "tasks", taskId);
|
|
53822
|
-
|
|
54540
|
+
const relatedValidations = resolveEntityValidations(dsl, "tasks", taskId);
|
|
54541
|
+
return { task, targetAgent, relatedGuardrails, relatedValidations, dsl };
|
|
53823
54542
|
}
|
|
53824
54543
|
function buildArtifactContext(dsl, artifactId) {
|
|
53825
54544
|
const artifactDef = dsl.artifacts[artifactId];
|
|
@@ -53890,12 +54609,14 @@ function buildToolContext(dsl, toolId) {
|
|
|
53890
54609
|
return result;
|
|
53891
54610
|
};
|
|
53892
54611
|
const relatedGuardrails = resolveEffectiveGuardrails(dsl, "tools", toolId);
|
|
54612
|
+
const relatedValidations = resolveEntityValidations(dsl, "tools", toolId);
|
|
53893
54613
|
return {
|
|
53894
54614
|
tool,
|
|
53895
54615
|
invokableAgents,
|
|
53896
54616
|
inputArtifactDetails: pickArtifacts(toolDef.input_artifacts),
|
|
53897
54617
|
outputArtifactDetails: pickArtifacts(toolDef.output_artifacts),
|
|
53898
54618
|
relatedGuardrails,
|
|
54619
|
+
relatedValidations,
|
|
53899
54620
|
dsl
|
|
53900
54621
|
};
|
|
53901
54622
|
}
|
|
@@ -54128,6 +54849,7 @@ function buildPerAgentContext(dsl, agent) {
|
|
|
54128
54849
|
const rawReceivableTasks = receivableTasks.map(({ id: _id, ...rest }) => rest);
|
|
54129
54850
|
const mergedBehavior = mergeBehavioralSpec(agent, rawReceivableTasks);
|
|
54130
54851
|
const relatedGuardrails = resolveEffectiveGuardrails(dsl, "agents", agentId);
|
|
54852
|
+
const relatedValidations = resolveEntityValidations(dsl, "agents", agentId);
|
|
54131
54853
|
return {
|
|
54132
54854
|
agent,
|
|
54133
54855
|
tasks: receivableTasks,
|
|
@@ -54138,6 +54860,7 @@ function buildPerAgentContext(dsl, agent) {
|
|
|
54138
54860
|
relatedHandoffTypes,
|
|
54139
54861
|
mergedBehavior,
|
|
54140
54862
|
relatedGuardrails,
|
|
54863
|
+
relatedValidations,
|
|
54141
54864
|
dsl
|
|
54142
54865
|
};
|
|
54143
54866
|
}
|
|
@@ -55150,6 +55873,9 @@ var checkCommand = new Command5("check").description("Run full pipeline: resolve
|
|
|
55150
55873
|
const resolved = await resolve4(config.dsl);
|
|
55151
55874
|
const data = config.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
55152
55875
|
const schemaResult = validateSchema(data);
|
|
55876
|
+
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
55877
|
+
(d2) => d2.severity === "warning"
|
|
55878
|
+
);
|
|
55153
55879
|
if (!schemaResult.success) {
|
|
55154
55880
|
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
55155
55881
|
format: opts.format,
|
|
@@ -55160,7 +55886,7 @@ var checkCommand = new Command5("check").description("Run full pipeline: resolve
|
|
|
55160
55886
|
}
|
|
55161
55887
|
const refDiags = checkReferences(schemaResult.data);
|
|
55162
55888
|
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
55163
|
-
const allRefDiags = [...refDiags, ...handoffDiags];
|
|
55889
|
+
const allRefDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
55164
55890
|
if (allRefDiags.length > 0) {
|
|
55165
55891
|
const output = formatDiagnostics(allRefDiags, {
|
|
55166
55892
|
format: opts.format,
|