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/dist/index.d.ts CHANGED
@@ -1034,8 +1034,18 @@ interface ResolvedConfig {
1034
1034
  paths?: Record<string, string>;
1035
1035
  }
1036
1036
 
1037
- declare function renderFromConfig(dsl: Dsl, renderTargets: ResolvedRenderTarget[]): Promise<string[]>;
1038
- declare function checkDriftFromConfig(dsl: Dsl, renderTargets: ResolvedRenderTarget[]): Promise<{
1037
+ interface LoadedBinding {
1038
+ filePath: string;
1039
+ binding: SoftwareBinding;
1040
+ }
1041
+ declare function loadBindings(bindingPaths: string[]): Promise<LoadedBinding[]>;
1042
+
1043
+ interface RenderOptions {
1044
+ loadedBindings?: LoadedBinding[];
1045
+ activeGuardrailPolicy?: string;
1046
+ }
1047
+ declare function renderFromConfig(dsl: Dsl, renderTargets: ResolvedRenderTarget[], options?: RenderOptions): Promise<string[]>;
1048
+ declare function checkDriftFromConfig(dsl: Dsl, renderTargets: ResolvedRenderTarget[], options?: RenderOptions): Promise<{
1039
1049
  hasDrift: boolean;
1040
1050
  diffs: string[];
1041
1051
  }>;
@@ -1054,9 +1064,29 @@ interface GlobalContext {
1054
1064
  guardrail_policies: Dsl["guardrail_policies"];
1055
1065
  [key: string]: unknown;
1056
1066
  }
1067
+ interface GuardrailEnforcementEntry {
1068
+ guardrail_id: string;
1069
+ description: string;
1070
+ severity: string;
1071
+ action: string;
1072
+ scoped_agents: string[];
1073
+ scoped_tasks: string[];
1074
+ scoped_workflows: string[];
1075
+ scoped_tools: string[];
1076
+ scoped_artifacts: string[];
1077
+ allow_override: boolean;
1078
+ override_requires: string[];
1079
+ trigger: string | null;
1080
+ escalation: {
1081
+ target: string;
1082
+ condition?: string;
1083
+ } | null;
1084
+ }
1057
1085
  interface SystemContext {
1058
1086
  system: System;
1059
1087
  dsl: Dsl;
1088
+ guardrailEnforcement?: GuardrailEnforcementEntry[];
1089
+ bindings?: SoftwareBinding[];
1060
1090
  [key: string]: unknown;
1061
1091
  }
1062
1092
  interface PerTaskContext {
@@ -1183,7 +1213,10 @@ interface PerAgentContext {
1183
1213
  [key: string]: unknown;
1184
1214
  }
1185
1215
  declare function buildGlobalContext(dsl: Dsl): GlobalContext;
1186
- declare function buildSystemContext(dsl: Dsl): SystemContext;
1216
+ declare function buildSystemContext(dsl: Dsl, options?: {
1217
+ loadedBindings?: LoadedBinding[];
1218
+ activeGuardrailPolicy?: string;
1219
+ }): SystemContext;
1187
1220
  declare function buildTaskContext(dsl: Dsl, taskId: string): PerTaskContext;
1188
1221
  declare function buildArtifactContext(dsl: Dsl, artifactId: string): PerArtifactContext;
1189
1222
  declare function buildToolContext(dsl: Dsl, toolId: string): PerToolContext;
@@ -1197,12 +1230,6 @@ declare function buildPerAgentContext(dsl: Dsl, agent: Agent & {
1197
1230
  id: string;
1198
1231
  }): PerAgentContext;
1199
1232
 
1200
- interface LoadedBinding {
1201
- filePath: string;
1202
- binding: SoftwareBinding;
1203
- }
1204
- declare function loadBindings(bindingPaths: string[]): Promise<LoadedBinding[]>;
1205
-
1206
1233
  declare class ConfigLoadError extends Error {
1207
1234
  readonly filePath?: string | undefined;
1208
1235
  constructor(message: string, filePath?: string | undefined);
package/dist/index.js CHANGED
@@ -53129,8 +53129,52 @@ function buildGlobalContext(dsl) {
53129
53129
  guardrail_policies: dsl.guardrail_policies
53130
53130
  };
53131
53131
  }
53132
- function buildSystemContext(dsl) {
53133
- return { system: dsl.system, dsl };
53132
+ function buildSystemContext(dsl, options) {
53133
+ const ctx = { system: dsl.system, dsl };
53134
+ if (options?.loadedBindings && options.loadedBindings.length > 0) {
53135
+ ctx.bindings = options.loadedBindings.map((lb) => lb.binding);
53136
+ const policyName = options.activeGuardrailPolicy;
53137
+ const policy = policyName ? dsl.guardrail_policies[policyName] : void 0;
53138
+ if (policy) {
53139
+ ctx.guardrailEnforcement = buildGuardrailEnforcement(dsl, policy, options.loadedBindings);
53140
+ }
53141
+ }
53142
+ return ctx;
53143
+ }
53144
+ function buildGuardrailEnforcement(dsl, policy, loadedBindings) {
53145
+ const entries = [];
53146
+ const bindingTriggers = /* @__PURE__ */ new Map();
53147
+ for (const lb of loadedBindings) {
53148
+ const impl = lb.binding.guardrail_impl ?? {};
53149
+ for (const [guardrailId, gi] of Object.entries(impl)) {
53150
+ for (const check of gi.checks) {
53151
+ if (check.matcher) {
53152
+ bindingTriggers.set(guardrailId, check.matcher.type);
53153
+ }
53154
+ }
53155
+ }
53156
+ }
53157
+ for (const rule of policy.rules) {
53158
+ const guardrail = dsl.guardrails[rule.guardrail];
53159
+ if (!guardrail) continue;
53160
+ const scope = guardrail.scope ?? {};
53161
+ entries.push({
53162
+ guardrail_id: rule.guardrail,
53163
+ description: guardrail.description,
53164
+ severity: rule.severity,
53165
+ action: rule.action,
53166
+ scoped_agents: scope.agents ?? [],
53167
+ scoped_tasks: scope.tasks ?? [],
53168
+ scoped_workflows: scope.workflows ?? [],
53169
+ scoped_tools: scope.tools ?? [],
53170
+ scoped_artifacts: scope.artifacts ?? [],
53171
+ allow_override: rule.allow_override,
53172
+ override_requires: rule.override_requires ?? [],
53173
+ trigger: bindingTriggers.get(rule.guardrail) ?? null,
53174
+ escalation: rule.escalation ? { target: rule.escalation.target, condition: rule.escalation.condition } : null
53175
+ });
53176
+ }
53177
+ return entries;
53134
53178
  }
53135
53179
  function buildTaskContext(dsl, taskId) {
53136
53180
  const taskDef = dsl.tasks[taskId];
@@ -54185,6 +54229,50 @@ Handlebars.registerHelper(
54185
54229
  return generateOverviewFlowchart(dsl);
54186
54230
  }
54187
54231
  );
54232
+ Handlebars.registerHelper(
54233
+ "guardrailCoverageMatrix",
54234
+ function() {
54235
+ const enforcement = this["guardrailEnforcement"];
54236
+ if (!enforcement || enforcement.length === 0) return "";
54237
+ const header = "| Guardrail | Severity | Action | Agents | Tasks | Workflows | Tools | Artifacts | Trigger | Override | Escalation |";
54238
+ const divider = "|-----------|----------|--------|--------|-------|-----------|-------|-----------|---------|----------|------------|";
54239
+ const rows = enforcement.map((e3) => {
54240
+ const agents = e3["scoped_agents"]?.join(", ") || "\u2014";
54241
+ const tasks = e3["scoped_tasks"]?.join(", ") || "\u2014";
54242
+ const workflows = e3["scoped_workflows"]?.join(", ") || "\u2014";
54243
+ const tools = e3["scoped_tools"]?.join(", ") || "\u2014";
54244
+ const artifacts = e3["scoped_artifacts"]?.join(", ") || "\u2014";
54245
+ const trigger = e3["trigger"] || "\u2014";
54246
+ const override = e3["allow_override"] ? "yes" : "no";
54247
+ const esc = e3["escalation"];
54248
+ const escalation = esc ? esc["target"] : "\u2014";
54249
+ return `| ${e3["guardrail_id"]} | ${e3["severity"]} | ${e3["action"]} | ${agents} | ${tasks} | ${workflows} | ${tools} | ${artifacts} | ${trigger} | ${override} | ${escalation} |`;
54250
+ });
54251
+ return [header, divider, ...rows].join("\n");
54252
+ }
54253
+ );
54254
+ Handlebars.registerHelper(
54255
+ "taskGuardrailMatrix",
54256
+ function() {
54257
+ const dsl = this["dsl"];
54258
+ const enforcement = this["guardrailEnforcement"];
54259
+ if (!dsl || !enforcement || enforcement.length === 0) return "";
54260
+ const taskIds = Object.keys(dsl.tasks);
54261
+ if (taskIds.length === 0) return "";
54262
+ const guardrailIds = enforcement.map((e3) => e3["guardrail_id"]);
54263
+ const header = `| Task | ${guardrailIds.join(" | ")} |`;
54264
+ const divider = `|------|${guardrailIds.map(() => "------").join("|")}|`;
54265
+ const rows = taskIds.map((taskId) => {
54266
+ const cells = enforcement.map((e3) => {
54267
+ const scopedTasks = e3["scoped_tasks"];
54268
+ if (scopedTasks.length > 0 && !scopedTasks.includes(taskId)) return "n/a";
54269
+ return e3["action"];
54270
+ });
54271
+ return `| ${taskId} | ${cells.join(" | ")} |`;
54272
+ });
54273
+ return [header, divider, ...rows].join("\n");
54274
+ }
54275
+ );
54188
54276
  function getDslSection(dsl, context) {
54189
54277
  const sectionMap = {
54190
54278
  agent: dsl.agents,
@@ -54249,13 +54337,13 @@ async function removeIfExists(filePath) {
54249
54337
  } catch {
54250
54338
  }
54251
54339
  }
54252
- async function renderFromConfig(dsl, renderTargets) {
54340
+ async function renderFromConfig(dsl, renderTargets, options) {
54253
54341
  const outputFiles = [];
54254
54342
  for (const target of renderTargets) {
54255
54343
  const templateContent = await loadTemplate(target.template);
54256
54344
  const compiled = Handlebars.compile(templateContent, { noEscape: false });
54257
54345
  if (target.context === "system") {
54258
- const ctx = buildSystemContext(dsl);
54346
+ const ctx = buildSystemContext(dsl, options);
54259
54347
  const output = compiled(ctx);
54260
54348
  if (target.skip_empty && isEffectivelyEmpty(output)) {
54261
54349
  await removeIfExists(target.output);
@@ -54304,13 +54392,13 @@ function checkExpectedVsExisting(expected, outputPath, skipEmpty, diffs) {
54304
54392
  diffs.push(outputPath);
54305
54393
  });
54306
54394
  }
54307
- async function checkDriftFromConfig(dsl, renderTargets) {
54395
+ async function checkDriftFromConfig(dsl, renderTargets, options) {
54308
54396
  const diffs = [];
54309
54397
  for (const target of renderTargets) {
54310
54398
  const templateContent = await loadTemplate(target.template);
54311
54399
  const compiled = Handlebars.compile(templateContent, { noEscape: false });
54312
54400
  if (target.context === "system") {
54313
- const ctx = buildSystemContext(dsl);
54401
+ const ctx = buildSystemContext(dsl, options);
54314
54402
  const expected = compiled(ctx);
54315
54403
  await checkExpectedVsExisting(expected, target.output, target.skip_empty, diffs);
54316
54404
  } else {