oh-my-promptfoo 1.17.0 → 1.18.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.
@@ -84,7 +84,6 @@ function prepareRubric(output, context2, workspace = false) {
84
84
  const config = context2?.config;
85
85
  const components = config?.components;
86
86
  const scoring = config?.scoring ?? "graded";
87
- const threshold = scoring === "binary" ? 1 : config?.threshold;
88
87
  if (config && Object.hasOwn(config, "rubric")) {
89
88
  throw new Error("LLM assertion config.rubric was renamed to config.rubricPrompt");
90
89
  }
@@ -100,9 +99,11 @@ function prepareRubric(output, context2, workspace = false) {
100
99
  }
101
100
  if (!config || !Array.isArray(components) || components.length === 0 || !components.every(
102
101
  (component) => component && typeof component.metric === "string" && component.metric.trim() && typeof component.value === "string" && component.value.trim() && (component.weight === void 0 || typeof component.weight === "number" && Number.isFinite(component.weight) && component.weight > 0)
103
- ) || new Set(components.map(({ metric }) => metric)).size !== components.length || threshold !== void 0 && (typeof threshold !== "number" || !Number.isFinite(threshold) || threshold < 0 || threshold > 1) || config.rubricPrompt !== void 0 && !config.rubricPrompt.trim() || config.scoring !== void 0 && config.scoring !== "graded" && config.scoring !== "binary" || scoring === "binary" && config.threshold !== void 0 && config.threshold !== 1) {
102
+ ) || new Set(components.map(({ metric }) => metric)).size !== components.length || ![config.threshold, ...components.map(({ threshold }) => threshold)].every(
103
+ (threshold) => threshold === void 0 || typeof threshold === "number" && Number.isFinite(threshold) && threshold >= 0 && threshold <= 1 && (scoring !== "binary" || threshold === 1)
104
+ ) || config.rubricPrompt !== void 0 && !config.rubricPrompt.trim() || config.scoring !== void 0 && config.scoring !== "graded" && config.scoring !== "binary") {
104
105
  throw new Error(
105
- "LLM assertion requires unique named components with nonempty criteria, positive weights, a threshold between 0 and 1, a nonempty string rubricPrompt, and scoring of 'graded' or 'binary' without a conflicting threshold"
106
+ "LLM assertion requires unique named components with nonempty criteria, positive weights, a config.threshold and component thresholds between 0 and 1, a nonempty string rubricPrompt, and scoring of 'graded' or 'binary' without a conflicting config.threshold or component threshold"
106
107
  );
107
108
  }
108
109
  if (components.some(({ metric }) => Object.hasOwn(Object.prototype, metric))) {
@@ -130,7 +131,15 @@ ${answer}
130
131
  <Rubric>
131
132
  ${criteria.map(({ metric, value }) => `- ${metric}: ${value}`).join("\n")}
132
133
  </Rubric>`;
133
- return { components, threshold, totalWeight, system, user };
134
+ return {
135
+ components: components.map((component) => ({
136
+ ...component,
137
+ threshold: scoring === "binary" ? 1 : component.threshold ?? config.threshold
138
+ })),
139
+ totalWeight,
140
+ system,
141
+ user
142
+ };
134
143
  }
135
144
  function parseVerdict(text) {
136
145
  try {
@@ -219,13 +228,13 @@ function gradingFailure(error, usages) {
219
228
  metadata: { graderError: true }
220
229
  };
221
230
  }
222
- function rubricResult({ components, threshold, totalWeight }, grades, usages, renderedGradingPrompt) {
231
+ function rubricResult({ components, totalWeight }, grades, usages, renderedGradingPrompt) {
223
232
  const namedScores = {};
224
233
  const namedScoreWeights = {};
225
234
  let weightedScore = 0;
226
235
  let allPassed = true;
227
236
  let reason = "";
228
- const componentResults = components.map(({ metric, value, weight }) => {
237
+ const componentResults = components.map(({ metric, value, weight, threshold }) => {
229
238
  const grade = grades.get(metric);
230
239
  if (!grade) throw new Error(`LLM grader did not score component: ${metric}`);
231
240
  const effectiveWeight = weight ?? 1;