agent-contracts 0.11.8 → 0.12.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 +13 -1
- package/dist/cli.js +106 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +36 -9
- package/dist/index.js +94 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -998,7 +998,7 @@ Each `context` type provides a different rendering scope:
|
|
|
998
998
|
|
|
999
999
|
| Context | Scope | Output | Key variables |
|
|
1000
1000
|
|---------|-------|--------|---------------|
|
|
1001
|
-
| `system` | Single file | `output` as-is | `system`, `dsl` |
|
|
1001
|
+
| `system` | Single file | `output` as-is | `system`, `dsl`, `guardrailEnforcement`\*, `bindings`\* |
|
|
1002
1002
|
| `agent` | Per agent | `{agent.id}` in output path | `agent`, `receivableTasks`, `delegatableTasks`, `relatedArtifacts`, `relatedTools`, `relatedHandoffTypes`, `mergedBehavior`, `dsl` |
|
|
1003
1003
|
| `task` | Per task | `{task.id}` in output path | `task`, `targetAgent`, `dsl` |
|
|
1004
1004
|
| `artifact` | Per artifact | `{artifact.id}` in output path | `artifact`, `relatedTools`, `relatedValidations`, `producerAgents`, `consumerAgents`, `editorAgents`, `createdInWorkflows`, `dsl` |
|
|
@@ -1027,6 +1027,18 @@ Each `context` type provides a different rendering scope:
|
|
|
1027
1027
|
* `producerAgents` / `consumerAgents` / `editorAgents` — resolved agent records
|
|
1028
1028
|
* `createdInWorkflows` — workflow phases where this artifact is written
|
|
1029
1029
|
|
|
1030
|
+
**`system` context** includes binding-aware guardrail enforcement data when `bindings` and `active_guardrail_policy` are configured:
|
|
1031
|
+
|
|
1032
|
+
* `guardrailEnforcement` — array of enforcement entries, each with `guardrail_id`, `description`, `severity`, `action`, scoped entities (`scoped_agents`, `scoped_tasks`, `scoped_workflows`, `scoped_tools`, `scoped_artifacts`), `allow_override`, `override_requires`, `trigger` (from binding matcher type), and `escalation`
|
|
1033
|
+
* `bindings` — array of loaded `SoftwareBinding` objects
|
|
1034
|
+
|
|
1035
|
+
These fields are only populated when the config specifies `bindings` and `active_guardrail_policy`. Existing templates that do not reference these fields are unaffected.
|
|
1036
|
+
|
|
1037
|
+
**Matrix helpers** are available in `context: system` templates:
|
|
1038
|
+
|
|
1039
|
+
* `guardrailCoverageMatrix` — generates a Guardrail Coverage Matrix table (guardrail × severity × action × scoped entities × trigger × override × escalation)
|
|
1040
|
+
* `taskGuardrailMatrix` — generates a Task × Guardrail cross-reference table showing which action applies to each task
|
|
1041
|
+
|
|
1030
1042
|
**`tool` context** resolves agent and artifact references:
|
|
1031
1043
|
|
|
1032
1044
|
* `invokableAgents` — agents listed in `invokable_by`
|
package/dist/cli.js
CHANGED
|
@@ -53574,8 +53574,52 @@ import { dirname as dirname5 } from "path";
|
|
|
53574
53574
|
import Handlebars from "handlebars";
|
|
53575
53575
|
|
|
53576
53576
|
// src/renderer/context.ts
|
|
53577
|
-
function buildSystemContext(dsl) {
|
|
53578
|
-
|
|
53577
|
+
function buildSystemContext(dsl, options) {
|
|
53578
|
+
const ctx = { system: dsl.system, dsl };
|
|
53579
|
+
if (options?.loadedBindings && options.loadedBindings.length > 0) {
|
|
53580
|
+
ctx.bindings = options.loadedBindings.map((lb) => lb.binding);
|
|
53581
|
+
const policyName = options.activeGuardrailPolicy;
|
|
53582
|
+
const policy = policyName ? dsl.guardrail_policies[policyName] : void 0;
|
|
53583
|
+
if (policy) {
|
|
53584
|
+
ctx.guardrailEnforcement = buildGuardrailEnforcement(dsl, policy, options.loadedBindings);
|
|
53585
|
+
}
|
|
53586
|
+
}
|
|
53587
|
+
return ctx;
|
|
53588
|
+
}
|
|
53589
|
+
function buildGuardrailEnforcement(dsl, policy, loadedBindings) {
|
|
53590
|
+
const entries = [];
|
|
53591
|
+
const bindingTriggers = /* @__PURE__ */ new Map();
|
|
53592
|
+
for (const lb of loadedBindings) {
|
|
53593
|
+
const impl = lb.binding.guardrail_impl ?? {};
|
|
53594
|
+
for (const [guardrailId, gi] of Object.entries(impl)) {
|
|
53595
|
+
for (const check of gi.checks) {
|
|
53596
|
+
if (check.matcher) {
|
|
53597
|
+
bindingTriggers.set(guardrailId, check.matcher.type);
|
|
53598
|
+
}
|
|
53599
|
+
}
|
|
53600
|
+
}
|
|
53601
|
+
}
|
|
53602
|
+
for (const rule of policy.rules) {
|
|
53603
|
+
const guardrail = dsl.guardrails[rule.guardrail];
|
|
53604
|
+
if (!guardrail) continue;
|
|
53605
|
+
const scope = guardrail.scope ?? {};
|
|
53606
|
+
entries.push({
|
|
53607
|
+
guardrail_id: rule.guardrail,
|
|
53608
|
+
description: guardrail.description,
|
|
53609
|
+
severity: rule.severity,
|
|
53610
|
+
action: rule.action,
|
|
53611
|
+
scoped_agents: scope.agents ?? [],
|
|
53612
|
+
scoped_tasks: scope.tasks ?? [],
|
|
53613
|
+
scoped_workflows: scope.workflows ?? [],
|
|
53614
|
+
scoped_tools: scope.tools ?? [],
|
|
53615
|
+
scoped_artifacts: scope.artifacts ?? [],
|
|
53616
|
+
allow_override: rule.allow_override,
|
|
53617
|
+
override_requires: rule.override_requires ?? [],
|
|
53618
|
+
trigger: bindingTriggers.get(rule.guardrail) ?? null,
|
|
53619
|
+
escalation: rule.escalation ? { target: rule.escalation.target, condition: rule.escalation.condition } : null
|
|
53620
|
+
});
|
|
53621
|
+
}
|
|
53622
|
+
return entries;
|
|
53579
53623
|
}
|
|
53580
53624
|
function buildTaskContext(dsl, taskId) {
|
|
53581
53625
|
const taskDef = dsl.tasks[taskId];
|
|
@@ -54630,6 +54674,50 @@ Handlebars.registerHelper(
|
|
|
54630
54674
|
return generateOverviewFlowchart(dsl);
|
|
54631
54675
|
}
|
|
54632
54676
|
);
|
|
54677
|
+
Handlebars.registerHelper(
|
|
54678
|
+
"guardrailCoverageMatrix",
|
|
54679
|
+
function() {
|
|
54680
|
+
const enforcement = this["guardrailEnforcement"];
|
|
54681
|
+
if (!enforcement || enforcement.length === 0) return "";
|
|
54682
|
+
const header = "| Guardrail | Severity | Action | Agents | Tasks | Workflows | Tools | Artifacts | Trigger | Override | Escalation |";
|
|
54683
|
+
const divider = "|-----------|----------|--------|--------|-------|-----------|-------|-----------|---------|----------|------------|";
|
|
54684
|
+
const rows = enforcement.map((e3) => {
|
|
54685
|
+
const agents = e3["scoped_agents"]?.join(", ") || "\u2014";
|
|
54686
|
+
const tasks = e3["scoped_tasks"]?.join(", ") || "\u2014";
|
|
54687
|
+
const workflows = e3["scoped_workflows"]?.join(", ") || "\u2014";
|
|
54688
|
+
const tools = e3["scoped_tools"]?.join(", ") || "\u2014";
|
|
54689
|
+
const artifacts = e3["scoped_artifacts"]?.join(", ") || "\u2014";
|
|
54690
|
+
const trigger = e3["trigger"] || "\u2014";
|
|
54691
|
+
const override = e3["allow_override"] ? "yes" : "no";
|
|
54692
|
+
const esc = e3["escalation"];
|
|
54693
|
+
const escalation = esc ? esc["target"] : "\u2014";
|
|
54694
|
+
return `| ${e3["guardrail_id"]} | ${e3["severity"]} | ${e3["action"]} | ${agents} | ${tasks} | ${workflows} | ${tools} | ${artifacts} | ${trigger} | ${override} | ${escalation} |`;
|
|
54695
|
+
});
|
|
54696
|
+
return [header, divider, ...rows].join("\n");
|
|
54697
|
+
}
|
|
54698
|
+
);
|
|
54699
|
+
Handlebars.registerHelper(
|
|
54700
|
+
"taskGuardrailMatrix",
|
|
54701
|
+
function() {
|
|
54702
|
+
const dsl = this["dsl"];
|
|
54703
|
+
const enforcement = this["guardrailEnforcement"];
|
|
54704
|
+
if (!dsl || !enforcement || enforcement.length === 0) return "";
|
|
54705
|
+
const taskIds = Object.keys(dsl.tasks);
|
|
54706
|
+
if (taskIds.length === 0) return "";
|
|
54707
|
+
const guardrailIds = enforcement.map((e3) => e3["guardrail_id"]);
|
|
54708
|
+
const header = `| Task | ${guardrailIds.join(" | ")} |`;
|
|
54709
|
+
const divider = `|------|${guardrailIds.map(() => "------").join("|")}|`;
|
|
54710
|
+
const rows = taskIds.map((taskId) => {
|
|
54711
|
+
const cells = enforcement.map((e3) => {
|
|
54712
|
+
const scopedTasks = e3["scoped_tasks"];
|
|
54713
|
+
if (scopedTasks.length > 0 && !scopedTasks.includes(taskId)) return "n/a";
|
|
54714
|
+
return e3["action"];
|
|
54715
|
+
});
|
|
54716
|
+
return `| ${taskId} | ${cells.join(" | ")} |`;
|
|
54717
|
+
});
|
|
54718
|
+
return [header, divider, ...rows].join("\n");
|
|
54719
|
+
}
|
|
54720
|
+
);
|
|
54633
54721
|
function getDslSection(dsl, context) {
|
|
54634
54722
|
const sectionMap = {
|
|
54635
54723
|
agent: dsl.agents,
|
|
@@ -54694,13 +54782,13 @@ async function removeIfExists(filePath) {
|
|
|
54694
54782
|
} catch {
|
|
54695
54783
|
}
|
|
54696
54784
|
}
|
|
54697
|
-
async function renderFromConfig(dsl, renderTargets) {
|
|
54785
|
+
async function renderFromConfig(dsl, renderTargets, options) {
|
|
54698
54786
|
const outputFiles = [];
|
|
54699
54787
|
for (const target of renderTargets) {
|
|
54700
54788
|
const templateContent = await loadTemplate(target.template);
|
|
54701
54789
|
const compiled = Handlebars.compile(templateContent, { noEscape: false });
|
|
54702
54790
|
if (target.context === "system") {
|
|
54703
|
-
const ctx = buildSystemContext(dsl);
|
|
54791
|
+
const ctx = buildSystemContext(dsl, options);
|
|
54704
54792
|
const output = compiled(ctx);
|
|
54705
54793
|
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
54706
54794
|
await removeIfExists(target.output);
|
|
@@ -54749,13 +54837,13 @@ function checkExpectedVsExisting(expected, outputPath, skipEmpty, diffs) {
|
|
|
54749
54837
|
diffs.push(outputPath);
|
|
54750
54838
|
});
|
|
54751
54839
|
}
|
|
54752
|
-
async function checkDriftFromConfig(dsl, renderTargets) {
|
|
54840
|
+
async function checkDriftFromConfig(dsl, renderTargets, options) {
|
|
54753
54841
|
const diffs = [];
|
|
54754
54842
|
for (const target of renderTargets) {
|
|
54755
54843
|
const templateContent = await loadTemplate(target.template);
|
|
54756
54844
|
const compiled = Handlebars.compile(templateContent, { noEscape: false });
|
|
54757
54845
|
if (target.context === "system") {
|
|
54758
|
-
const ctx = buildSystemContext(dsl);
|
|
54846
|
+
const ctx = buildSystemContext(dsl, options);
|
|
54759
54847
|
const expected = compiled(ctx);
|
|
54760
54848
|
await checkExpectedVsExisting(expected, target.output, target.skip_empty, diffs);
|
|
54761
54849
|
} else {
|
|
@@ -54793,10 +54881,19 @@ var renderCommand = new Command4("render").description("Render resolved DSL with
|
|
|
54793
54881
|
);
|
|
54794
54882
|
process.exit(1);
|
|
54795
54883
|
}
|
|
54884
|
+
let renderOptions;
|
|
54885
|
+
if (config.bindings.length > 0) {
|
|
54886
|
+
const loadedBindings = await loadBindings(config.bindings);
|
|
54887
|
+
renderOptions = {
|
|
54888
|
+
loadedBindings,
|
|
54889
|
+
activeGuardrailPolicy: config.activeGuardrailPolicy
|
|
54890
|
+
};
|
|
54891
|
+
}
|
|
54796
54892
|
if (opts.check) {
|
|
54797
54893
|
const drift = await checkDriftFromConfig(
|
|
54798
54894
|
schemaResult.data,
|
|
54799
|
-
config.renders
|
|
54895
|
+
config.renders,
|
|
54896
|
+
renderOptions
|
|
54800
54897
|
);
|
|
54801
54898
|
if (drift.hasDrift) {
|
|
54802
54899
|
process.stderr.write("Drift detected in the following files:\n");
|
|
@@ -54812,7 +54909,8 @@ var renderCommand = new Command4("render").description("Render resolved DSL with
|
|
|
54812
54909
|
} else {
|
|
54813
54910
|
const files = await renderFromConfig(
|
|
54814
54911
|
schemaResult.data,
|
|
54815
|
-
config.renders
|
|
54912
|
+
config.renders,
|
|
54913
|
+
renderOptions
|
|
54816
54914
|
);
|
|
54817
54915
|
if (!opts.quiet) {
|
|
54818
54916
|
process.stdout.write(`Rendered ${files.length} file(s):
|