{"version":3,"sources":["../src/eval-format.ts"],"names":["EVAL_FORMAT_VERSION","isRecord","v","assert","cond","msg","validateEvalSuite","raw","cases","c","i","t","validateEvalRunResult","matchesExpectation","output","expected","normalize"],"mappings":"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","file":"eval-format.cjs","sourcesContent":["/**\n * Open Eval Format — a portable JSON file that describes an eval\n * suite (inputs, expected outputs, pass/fail rules) plus an\n * execution result. Compatible with standard CI reporters so one\n * dataset can be shared across frameworks.\n *\n * Version: 2026-04.\n */\n\nexport const EVAL_FORMAT_VERSION = '2026-04'\n\nexport interface EvalCaseExpectation {\n  /** Literal substring match. */\n  contains?: string\n  /** Regular-expression source (body + flags separate, no surrounding slashes). */\n  regex?: { body: string; flags?: string }\n  /** Equality check after trim + lowercase normalization. */\n  equalsNormalized?: string\n  /** Min similarity (0..1) after embedding; depends on runner impl. */\n  semanticSimilarity?: number\n}\n\nexport interface EvalCase {\n  id: string\n  input: string\n  expected?: EvalCaseExpectation | string\n  metadata?: Record<string, unknown>\n}\n\nexport interface EvalSuiteDoc {\n  evalFormatVersion: typeof EVAL_FORMAT_VERSION\n  name: string\n  description?: string\n  tags?: string[]\n  cases: EvalCase[]\n}\n\nexport interface EvalRunResult {\n  evalFormatVersion: typeof EVAL_FORMAT_VERSION\n  suite: string\n  startedAt: string\n  completedAt: string\n  agent: { name?: string; version?: string }\n  totals: {\n    cases: number\n    passed: number\n    failed: number\n    accuracy: number\n  }\n  cases: Array<{\n    id: string\n    input: string\n    output: string\n    passed: boolean\n    latencyMs: number\n    error?: string\n  }>\n}\n\n// ---------------------------------------------------------------------------\n// Validators\n// ---------------------------------------------------------------------------\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction assert(cond: unknown, msg: string): asserts cond {\n  if (!cond) throw new Error(`Invalid eval format: ${msg}`)\n}\n\nexport function validateEvalSuite(raw: unknown): EvalSuiteDoc {\n  assert(isRecord(raw), 'root must be an object')\n  assert(raw.evalFormatVersion === EVAL_FORMAT_VERSION, `evalFormatVersion must be \"${EVAL_FORMAT_VERSION}\"`)\n  assert(typeof raw.name === 'string', 'name required')\n  assert(Array.isArray(raw.cases), 'cases must be array')\n\n  const cases = raw.cases.map((c: unknown, i: number): EvalCase => {\n    assert(isRecord(c), `cases[${i}] must be an object`)\n    assert(typeof c.id === 'string', `cases[${i}].id required`)\n    assert(typeof c.input === 'string', `cases[${i}].input required`)\n    return c as unknown as EvalCase\n  })\n\n  return {\n    evalFormatVersion: EVAL_FORMAT_VERSION,\n    name: raw.name,\n    description: typeof raw.description === 'string' ? raw.description : undefined,\n    tags: Array.isArray(raw.tags) && raw.tags.every(t => typeof t === 'string') ? (raw.tags as string[]) : undefined,\n    cases,\n  }\n}\n\nexport function validateEvalRunResult(raw: unknown): EvalRunResult {\n  assert(isRecord(raw), 'root must be an object')\n  assert(raw.evalFormatVersion === EVAL_FORMAT_VERSION, `evalFormatVersion must be \"${EVAL_FORMAT_VERSION}\"`)\n  assert(typeof raw.suite === 'string', 'suite required')\n  assert(Array.isArray(raw.cases), 'cases must be array')\n  assert(isRecord(raw.totals), 'totals required')\n  return raw as unknown as EvalRunResult\n}\n\n/**\n * Evaluate whether an output satisfies a case's expectation.\n * Exported so custom runners can share the interpretation.\n */\nexport function matchesExpectation(output: string, expected: EvalCase['expected']): boolean {\n  if (!expected) return true\n  if (typeof expected === 'string') return output.includes(expected)\n  if (expected.contains) return output.includes(expected.contains)\n  if (expected.regex) {\n    const pattern = new RegExp(expected.regex.body, expected.regex.flags)\n    return pattern.test(output)\n  }\n  if (expected.equalsNormalized) {\n    const normalize = (s: string): string => s.trim().toLowerCase().replace(/\\s+/g, ' ')\n    return normalize(output) === normalize(expected.equalsNormalized)\n  }\n  // semanticSimilarity requires a runner-supplied embedder; not validated here.\n  return true\n}\n"]}