agent-contracts 0.12.0 → 0.12.2

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/cli.js CHANGED
@@ -2243,7 +2243,7 @@ var require_lodash = __commonJS({
2243
2243
  } else {
2244
2244
  newValue = [];
2245
2245
  }
2246
- } else if (isPlainObject(srcValue) || isArguments(srcValue)) {
2246
+ } else if (isPlainObject2(srcValue) || isArguments(srcValue)) {
2247
2247
  newValue = objValue;
2248
2248
  if (isArguments(objValue)) {
2249
2249
  newValue = toPlainObject(objValue);
@@ -3207,7 +3207,7 @@ var require_lodash = __commonJS({
3207
3207
  return objValue;
3208
3208
  }
3209
3209
  function customOmitClone(value) {
3210
- return isPlainObject(value) ? undefined2 : value;
3210
+ return isPlainObject2(value) ? undefined2 : value;
3211
3211
  }
3212
3212
  function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
3213
3213
  var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length;
@@ -4708,7 +4708,7 @@ var require_lodash = __commonJS({
4708
4708
  var isBuffer = nativeIsBuffer || stubFalse;
4709
4709
  var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
4710
4710
  function isElement(value) {
4711
- return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
4711
+ return isObjectLike(value) && value.nodeType === 1 && !isPlainObject2(value);
4712
4712
  }
4713
4713
  function isEmpty(value) {
4714
4714
  if (value == null) {
@@ -4744,7 +4744,7 @@ var require_lodash = __commonJS({
4744
4744
  return false;
4745
4745
  }
4746
4746
  var tag = baseGetTag(value);
4747
- return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value);
4747
+ return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject2(value);
4748
4748
  }
4749
4749
  function isFinite2(value) {
4750
4750
  return typeof value == "number" && nativeIsFinite(value);
@@ -4795,7 +4795,7 @@ var require_lodash = __commonJS({
4795
4795
  function isNumber(value) {
4796
4796
  return typeof value == "number" || isObjectLike(value) && baseGetTag(value) == numberTag;
4797
4797
  }
4798
- function isPlainObject(value) {
4798
+ function isPlainObject2(value) {
4799
4799
  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
4800
4800
  return false;
4801
4801
  }
@@ -5866,7 +5866,7 @@ var require_lodash = __commonJS({
5866
5866
  lodash.isNumber = isNumber;
5867
5867
  lodash.isObject = isObject2;
5868
5868
  lodash.isObjectLike = isObjectLike;
5869
- lodash.isPlainObject = isPlainObject;
5869
+ lodash.isPlainObject = isPlainObject2;
5870
5870
  lodash.isRegExp = isRegExp;
5871
5871
  lodash.isSafeInteger = isSafeInteger;
5872
5872
  lodash.isSet = isSet;
@@ -17506,10 +17506,10 @@ var require_immer_cjs_development = __commonJS({
17506
17506
  function isDraftable(value) {
17507
17507
  var _value$constructor;
17508
17508
  if (!value) return false;
17509
- return isPlainObject(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!((_value$constructor = value.constructor) === null || _value$constructor === void 0 ? void 0 : _value$constructor[DRAFTABLE]) || isMap(value) || isSet(value);
17509
+ return isPlainObject2(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!((_value$constructor = value.constructor) === null || _value$constructor === void 0 ? void 0 : _value$constructor[DRAFTABLE]) || isMap(value) || isSet(value);
17510
17510
  }
17511
17511
  var objectCtorString = /* @__PURE__ */ Object.prototype.constructor.toString();
17512
- function isPlainObject(value) {
17512
+ function isPlainObject2(value) {
17513
17513
  if (!value || typeof value !== "object") return false;
17514
17514
  var proto = Object.getPrototypeOf(value);
17515
17515
  if (proto === null) {
@@ -40192,10 +40192,10 @@ var require_object_inspect = __commonJS({
40192
40192
  }
40193
40193
  if (!isDate(obj) && !isRegExp(obj)) {
40194
40194
  var ys = arrObjKeys(obj, inspect);
40195
- var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
40195
+ var isPlainObject2 = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
40196
40196
  var protoTag = obj instanceof Object ? "" : "null prototype";
40197
- var stringTag = !isPlainObject && toStringTag2 && Object(obj) === obj && toStringTag2 in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : "";
40198
- var constructorTag = isPlainObject || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "";
40197
+ var stringTag = !isPlainObject2 && toStringTag2 && Object(obj) === obj && toStringTag2 in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : "";
40198
+ var constructorTag = isPlainObject2 || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "";
40199
40199
  var tag = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : "");
40200
40200
  if (ys.length === 0) {
40201
40201
  return tag + "{}";
@@ -44530,7 +44530,7 @@ var require_lodash3 = __commonJS({
44530
44530
  } else {
44531
44531
  newValue = [];
44532
44532
  }
44533
- } else if (isPlainObject(srcValue) || isArguments(srcValue)) {
44533
+ } else if (isPlainObject2(srcValue) || isArguments(srcValue)) {
44534
44534
  newValue = objValue;
44535
44535
  if (isArguments(objValue)) {
44536
44536
  newValue = toPlainObject(objValue);
@@ -45501,7 +45501,7 @@ var require_lodash3 = __commonJS({
45501
45501
  return objValue;
45502
45502
  }
45503
45503
  function customOmitClone(value) {
45504
- return isPlainObject(value) ? undefined2 : value;
45504
+ return isPlainObject2(value) ? undefined2 : value;
45505
45505
  }
45506
45506
  function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
45507
45507
  var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length;
@@ -47002,7 +47002,7 @@ var require_lodash3 = __commonJS({
47002
47002
  var isBuffer = nativeIsBuffer || stubFalse;
47003
47003
  var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
47004
47004
  function isElement(value) {
47005
- return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
47005
+ return isObjectLike(value) && value.nodeType === 1 && !isPlainObject2(value);
47006
47006
  }
47007
47007
  function isEmpty(value) {
47008
47008
  if (value == null) {
@@ -47038,7 +47038,7 @@ var require_lodash3 = __commonJS({
47038
47038
  return false;
47039
47039
  }
47040
47040
  var tag = baseGetTag(value);
47041
- return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value);
47041
+ return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject2(value);
47042
47042
  }
47043
47043
  function isFinite2(value) {
47044
47044
  return typeof value == "number" && nativeIsFinite(value);
@@ -47089,7 +47089,7 @@ var require_lodash3 = __commonJS({
47089
47089
  function isNumber(value) {
47090
47090
  return typeof value == "number" || isObjectLike(value) && baseGetTag(value) == numberTag;
47091
47091
  }
47092
- function isPlainObject(value) {
47092
+ function isPlainObject2(value) {
47093
47093
  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
47094
47094
  return false;
47095
47095
  }
@@ -48155,7 +48155,7 @@ var require_lodash3 = __commonJS({
48155
48155
  lodash.isNumber = isNumber;
48156
48156
  lodash.isObject = isObject2;
48157
48157
  lodash.isObjectLike = isObjectLike;
48158
- lodash.isPlainObject = isPlainObject;
48158
+ lodash.isPlainObject = isPlainObject2;
48159
48159
  lodash.isRegExp = isRegExp;
48160
48160
  lodash.isSafeInteger = isSafeInteger;
48161
48161
  lodash.isSet = isSet;
@@ -50527,13 +50527,20 @@ var BindingOutputSchema = z3.object({
50527
50527
  target: z3.string(),
50528
50528
  template: z3.string().optional(),
50529
50529
  inline_template: z3.string().optional(),
50530
+ source: z3.string().optional(),
50530
50531
  mode: z3.enum(["write", "patch"]).default("write"),
50532
+ format: z3.enum(["json", "yaml", "text"]).optional(),
50533
+ patch_strategy: z3.enum(["deep_merge", "append"]).optional(),
50534
+ array_merge_key: z3.string().optional(),
50531
50535
  group_by: z3.string().optional(),
50532
50536
  executable: z3.boolean().optional(),
50533
50537
  skip_empty: z3.boolean().optional()
50534
50538
  }).passthrough().refine(
50535
- (data) => !(data.template && data.inline_template),
50536
- { message: "template and inline_template are mutually exclusive" }
50539
+ (data) => {
50540
+ const count = [data.template, data.inline_template, data.source].filter(Boolean).length;
50541
+ return count === 1 || count === 0;
50542
+ },
50543
+ { message: "Only one of template, inline_template, or source may be specified" }
50537
50544
  );
50538
50545
  var ReportingSchema = z3.object({
50539
50546
  commands: z3.record(z3.string(), z3.string()),
@@ -54986,9 +54993,18 @@ var checkCommand = new Command5("check").description("Run full pipeline: resolve
54986
54993
  hasErrors = true;
54987
54994
  }
54988
54995
  }
54996
+ let renderOptions;
54997
+ if (config.bindings.length > 0) {
54998
+ const loadedBindings = await loadBindings(config.bindings);
54999
+ renderOptions = {
55000
+ loadedBindings,
55001
+ activeGuardrailPolicy: config.activeGuardrailPolicy
55002
+ };
55003
+ }
54989
55004
  const drift = await checkDriftFromConfig(
54990
55005
  schemaResult.data,
54991
- config.renders
55006
+ config.renders,
55007
+ renderOptions
54992
55008
  );
54993
55009
  if (drift.hasDrift) {
54994
55010
  process.stderr.write("Drift detected in:\n");
@@ -55022,9 +55038,10 @@ var checkCommand = new Command5("check").description("Run full pipeline: resolve
55022
55038
  import { Command as Command6 } from "commander";
55023
55039
 
55024
55040
  // src/guardrail-generator/generator.ts
55025
- import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2 } from "fs/promises";
55041
+ import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2, copyFile } from "fs/promises";
55026
55042
  import { resolve as resolve6, dirname as dirname6 } from "path";
55027
55043
  import Handlebars2 from "handlebars";
55044
+ import YAML from "yaml";
55028
55045
 
55029
55046
  // src/guardrail-generator/resolve-checks.ts
55030
55047
  function resolveChecks(dsl, binding, policy) {
@@ -55096,6 +55113,81 @@ Handlebars2.registerHelper(
55096
55113
  return new Handlebars2.SafeString(result);
55097
55114
  }
55098
55115
  );
55116
+ function isPlainObject(val) {
55117
+ return typeof val === "object" && val !== null && !Array.isArray(val);
55118
+ }
55119
+ function deepMergeArrays(existing, incoming, mergeKey) {
55120
+ if (!mergeKey) return [...existing, ...incoming];
55121
+ const merged = [...existing];
55122
+ for (const item of incoming) {
55123
+ if (isPlainObject(item) && mergeKey in item) {
55124
+ const idx = merged.findIndex(
55125
+ (e3) => isPlainObject(e3) && e3[mergeKey] === item[mergeKey]
55126
+ );
55127
+ if (idx >= 0) {
55128
+ merged[idx] = item;
55129
+ } else {
55130
+ merged.push(item);
55131
+ }
55132
+ } else {
55133
+ merged.push(item);
55134
+ }
55135
+ }
55136
+ return merged;
55137
+ }
55138
+ function deepMerge(existing, incoming, arrayMergeKey) {
55139
+ if (Array.isArray(existing) && Array.isArray(incoming)) {
55140
+ return deepMergeArrays(existing, incoming, arrayMergeKey);
55141
+ }
55142
+ if (isPlainObject(existing) && isPlainObject(incoming)) {
55143
+ const result = { ...existing };
55144
+ for (const [key, val] of Object.entries(incoming)) {
55145
+ result[key] = key in result ? deepMerge(result[key], val, arrayMergeKey) : val;
55146
+ }
55147
+ return result;
55148
+ }
55149
+ return incoming;
55150
+ }
55151
+ function parseContent(raw, format2) {
55152
+ if (format2 === "json") return JSON.parse(raw);
55153
+ if (format2 === "yaml") return YAML.parse(raw);
55154
+ throw new Error(`Unsupported format for patch parsing: ${format2}`);
55155
+ }
55156
+ function serializeContent(data, format2) {
55157
+ if (format2 === "json") return JSON.stringify(data, null, 2) + "\n";
55158
+ if (format2 === "yaml") return YAML.stringify(data);
55159
+ throw new Error(`Unsupported format for patch serialization: ${format2}`);
55160
+ }
55161
+ async function applyPatch(targetPath, patchContent, outputDef) {
55162
+ const format2 = outputDef.format ?? "json";
55163
+ if (format2 === "text") {
55164
+ let existing = "";
55165
+ try {
55166
+ existing = await readFile5(targetPath, "utf8");
55167
+ } catch {
55168
+ }
55169
+ return existing + patchContent;
55170
+ }
55171
+ const patchData = parseContent(patchContent, format2);
55172
+ let existingData;
55173
+ try {
55174
+ const existingRaw = await readFile5(targetPath, "utf8");
55175
+ existingData = parseContent(existingRaw, format2);
55176
+ } catch {
55177
+ return serializeContent(patchData, format2);
55178
+ }
55179
+ const strategy = outputDef.patch_strategy ?? "deep_merge";
55180
+ if (strategy === "append" && Array.isArray(existingData)) {
55181
+ const merged2 = deepMergeArrays(
55182
+ existingData,
55183
+ Array.isArray(patchData) ? patchData : [patchData],
55184
+ outputDef.array_merge_key
55185
+ );
55186
+ return serializeContent(merged2, format2);
55187
+ }
55188
+ const merged = deepMerge(existingData, patchData, outputDef.array_merge_key);
55189
+ return serializeContent(merged, format2);
55190
+ }
55099
55191
  async function generateGuardrails(options) {
55100
55192
  const { dsl, config, loadedBindings, filterBindings, dryRun } = options;
55101
55193
  const outputFiles = [];
@@ -55165,6 +55257,31 @@ async function generateGuardrails(options) {
55165
55257
  continue;
55166
55258
  }
55167
55259
  const targetPath = resolve6(config.configDir, pathResult.resolved);
55260
+ if (outputDef.source) {
55261
+ const sourcePath = resolve6(config.configDir, outputDef.source);
55262
+ if (!dryRun) {
55263
+ try {
55264
+ await mkdir2(dirname6(targetPath), { recursive: true });
55265
+ await copyFile(sourcePath, targetPath);
55266
+ if (outputDef.executable) {
55267
+ await chmod(targetPath, 493);
55268
+ }
55269
+ } catch (err) {
55270
+ const code = err.code;
55271
+ if (code === "ENOENT") {
55272
+ diagnostics.push({
55273
+ path: `binding.${binding.software}.outputs.${outputId}`,
55274
+ message: `Source file not found: ${sourcePath}`,
55275
+ severity: "error"
55276
+ });
55277
+ continue;
55278
+ }
55279
+ throw err;
55280
+ }
55281
+ }
55282
+ outputFiles.push(targetPath);
55283
+ continue;
55284
+ }
55168
55285
  let templateContent;
55169
55286
  if (outputDef.inline_template) {
55170
55287
  templateContent = outputDef.inline_template;
@@ -55191,12 +55308,13 @@ async function generateGuardrails(options) {
55191
55308
  } else {
55192
55309
  diagnostics.push({
55193
55310
  path: `binding.${binding.software}.outputs.${outputId}`,
55194
- message: "Output has neither template nor inline_template",
55311
+ message: "Output has neither template, inline_template, nor source",
55195
55312
  severity: "error"
55196
55313
  });
55197
55314
  continue;
55198
55315
  }
55199
55316
  const shouldSkipEmpty = outputDef.skip_empty === true;
55317
+ const isPatch = outputDef.mode === "patch";
55200
55318
  if (outputDef.group_by) {
55201
55319
  const groupField = outputDef.group_by;
55202
55320
  const groups = /* @__PURE__ */ new Map();
@@ -55214,9 +55332,9 @@ async function generateGuardrails(options) {
55214
55332
  current_group: groupKey
55215
55333
  };
55216
55334
  const compiled = Handlebars2.compile(templateContent, { noEscape: true });
55217
- const output = compiled(groupCtx);
55335
+ const rendered = compiled(groupCtx);
55218
55336
  const groupTarget = resolve6(targetPath, groupKey);
55219
- if (shouldSkipEmpty && output.trim().length === 0) {
55337
+ if (shouldSkipEmpty && rendered.trim().length === 0) {
55220
55338
  if (!dryRun) {
55221
55339
  try {
55222
55340
  await unlink2(groupTarget);
@@ -55225,6 +55343,7 @@ async function generateGuardrails(options) {
55225
55343
  }
55226
55344
  continue;
55227
55345
  }
55346
+ const output = isPatch && !dryRun ? await applyPatch(groupTarget, rendered, outputDef) : rendered;
55228
55347
  if (!dryRun) {
55229
55348
  await mkdir2(dirname6(groupTarget), { recursive: true });
55230
55349
  await writeFile2(groupTarget, output, "utf8");
@@ -55236,8 +55355,8 @@ async function generateGuardrails(options) {
55236
55355
  }
55237
55356
  } else {
55238
55357
  const compiled = Handlebars2.compile(templateContent, { noEscape: true });
55239
- const output = compiled(ctx);
55240
- if (shouldSkipEmpty && output.trim().length === 0) {
55358
+ const rendered = compiled(ctx);
55359
+ if (shouldSkipEmpty && rendered.trim().length === 0) {
55241
55360
  if (!dryRun) {
55242
55361
  try {
55243
55362
  await unlink2(targetPath);
@@ -55245,6 +55364,7 @@ async function generateGuardrails(options) {
55245
55364
  }
55246
55365
  }
55247
55366
  } else {
55367
+ const output = isPatch && !dryRun ? await applyPatch(targetPath, rendered, outputDef) : rendered;
55248
55368
  if (!dryRun) {
55249
55369
  await mkdir2(dirname6(targetPath), { recursive: true });
55250
55370
  await writeFile2(targetPath, output, "utf8");