import {
  validateRunRecord
} from "./chunk-TSPOEDM3.js";
import {
  pairedBootstrap,
  wilcoxonSignedRank
} from "./chunk-KHZRNY3F.js";

// src/feedback-trajectory.ts
var DEFAULT_SPLIT_POLICY = {
  trainPct: 70,
  devPct: 15,
  testPct: 10,
  holdoutPct: 5
};
var InMemoryFeedbackTrajectoryStore = class {
  trajectories = /* @__PURE__ */ new Map();
  async save(trajectory) {
    this.trajectories.set(trajectory.id, cloneTrajectory(trajectory));
  }
  async get(id) {
    const trajectory = this.trajectories.get(id);
    return trajectory ? cloneTrajectory(trajectory) : null;
  }
  async list(filter = {}) {
    return [...this.trajectories.values()].filter((trajectory) => matchesFilter(trajectory, filter)).map(cloneTrajectory);
  }
  async appendAttempt(id, attempt) {
    const trajectory = this.trajectories.get(id);
    if (!trajectory)
      throw new Error(`FeedbackTrajectoryStore.appendAttempt: unknown trajectory "${id}"`);
    const next = cloneTrajectory({
      ...trajectory,
      attempts: [...trajectory.attempts, attempt],
      updatedAt: attempt.createdAt
    });
    this.trajectories.set(id, next);
    return cloneTrajectory(next);
  }
  async appendLabel(id, label, attemptId) {
    const trajectory = this.trajectories.get(id);
    if (!trajectory)
      throw new Error(`FeedbackTrajectoryStore.appendLabel: unknown trajectory "${id}"`);
    const attempts = attemptId ? trajectory.attempts.map(
      (attempt) => attempt.id === attemptId ? { ...attempt, feedback: [...attempt.feedback ?? [], label] } : attempt
    ) : trajectory.attempts;
    const next = cloneTrajectory({
      ...trajectory,
      attempts,
      labels: attemptId ? trajectory.labels : [...trajectory.labels, label],
      updatedAt: label.createdAt
    });
    this.trajectories.set(id, next);
    return cloneTrajectory(next);
  }
};
var FileSystemFeedbackTrajectoryStore = class {
  dir;
  memory = new InMemoryFeedbackTrajectoryStore();
  loaded = false;
  constructor(options) {
    this.dir = options.dir;
  }
  async save(trajectory) {
    await this.load();
    await this.memory.save(trajectory);
    await this.append({ op: "save", trajectory });
  }
  async get(id) {
    await this.load();
    return this.memory.get(id);
  }
  async list(filter = {}) {
    await this.load();
    return this.memory.list(filter);
  }
  async appendAttempt(id, attempt) {
    await this.load();
    const next = await this.memory.appendAttempt(id, attempt);
    await this.append({ op: "appendAttempt", id, attempt });
    return next;
  }
  async appendLabel(id, label, attemptId) {
    await this.load();
    const next = await this.memory.appendLabel(id, label, attemptId);
    await this.append({ op: "appendLabel", id, label, attemptId });
    return next;
  }
  async append(record) {
    const { appendFile, mkdir } = await import("fs/promises");
    const { join } = await import("path");
    await mkdir(this.dir, { recursive: true });
    await appendFile(
      join(this.dir, "feedback-trajectories.ndjson"),
      `${JSON.stringify(record)}
`,
      "utf8"
    );
  }
  async load() {
    if (this.loaded) return;
    const { readFile } = await import("fs/promises");
    const { join } = await import("path");
    const file = join(this.dir, "feedback-trajectories.ndjson");
    try {
      const raw = await readFile(file, "utf8");
      for (const line of raw.split("\n")) {
        if (!line.trim()) continue;
        try {
          const record = JSON.parse(line);
          if (record.op === "save") await this.memory.save(record.trajectory);
          if (record.op === "appendAttempt")
            await this.memory.appendAttempt(record.id, record.attempt);
          if (record.op === "appendLabel")
            await this.memory.appendLabel(record.id, record.label, record.attemptId);
        } catch {
        }
      }
    } catch {
    }
    this.loaded = true;
  }
};
function createFeedbackTrajectory(input) {
  const createdAt = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
  const id = input.id ?? `ft_${stableHash(`${input.projectId ?? ""}|${input.scenarioId ?? ""}|${input.task.intent}|${createdAt}`).toString(16)}`;
  return {
    id,
    projectId: input.projectId,
    scenarioId: input.scenarioId,
    task: input.task,
    attempts: input.attempts ?? [],
    labels: input.labels ?? [],
    outcome: input.outcome,
    split: input.split,
    tags: input.tags,
    createdAt,
    metadata: input.metadata
  };
}
function assignFeedbackSplit(trajectory, policy = {}) {
  const split = { ...DEFAULT_SPLIT_POLICY, ...policy };
  const total = split.trainPct + split.devPct + split.testPct + split.holdoutPct;
  if (total <= 0) throw new Error("assignFeedbackSplit: split percentages must sum above zero");
  const bucket = stableHash(
    `${trajectory.projectId ?? ""}|${trajectory.scenarioId ?? ""}|${trajectory.id}|${trajectory.task.intent}`
  ) % total;
  if (bucket < split.trainPct) return "train";
  if (bucket < split.trainPct + split.devPct) return "dev";
  if (bucket < split.trainPct + split.devPct + split.testPct) return "test";
  return "holdout";
}
function withAssignedFeedbackSplit(trajectory, policy) {
  return {
    ...trajectory,
    split: trajectory.split ?? assignFeedbackSplit(trajectory, policy)
  };
}
function feedbackTrajectoryToDatasetScenario(trajectory) {
  const withSplit = withAssignedFeedbackSplit(trajectory);
  return {
    id: withSplit.scenarioId ?? withSplit.id,
    split: withSplit.split,
    payload: withSplit,
    tags: {
      ...withSplit.projectId ? { projectId: withSplit.projectId } : {},
      ...withSplit.tags ?? {},
      source: "feedback-trajectory"
    }
  };
}
function feedbackTrajectoriesToDatasetScenarios(trajectories) {
  return trajectories.map(feedbackTrajectoryToDatasetScenario);
}
function feedbackTrajectoryToOptimizerRow(trajectory) {
  const labels = allLabels(trajectory);
  return {
    scenarioId: trajectory.scenarioId ?? trajectory.id,
    trajectoryId: trajectory.id,
    labelKinds: [...new Set(labels.map((label) => label.kind))],
    score: trajectory.outcome?.score ?? scoreFromLabels(labels),
    metadata: {
      projectId: trajectory.projectId,
      split: trajectory.split,
      intent: trajectory.task.intent,
      attempts: trajectory.attempts.length,
      outcome: trajectory.outcome,
      labels
    }
  };
}
function feedbackTrajectoriesToOptimizerRows(trajectories) {
  return trajectories.map(feedbackTrajectoryToOptimizerRow);
}
async function replayFeedbackTrajectory(trajectory, adapter) {
  try {
    const result = await adapter.replay(trajectory);
    return {
      trajectoryId: trajectory.id,
      ...result
    };
  } catch (err) {
    const createdAt = (/* @__PURE__ */ new Date()).toISOString();
    const message = err instanceof Error ? err.message : String(err);
    return {
      trajectoryId: trajectory.id,
      pass: false,
      labels: [
        {
          source: "system",
          kind: "reject",
          value: false,
          reason: message,
          severity: "error",
          createdAt
        }
      ],
      outcome: {
        success: false,
        score: 0,
        detail: message,
        observedAt: createdAt
      },
      metadata: { replayError: true }
    };
  }
}
async function replayFeedbackTrajectories(trajectories, adapter) {
  const results = [];
  for (const trajectory of trajectories) {
    results.push(await replayFeedbackTrajectory(trajectory, adapter));
  }
  return results;
}
function summarizePreferenceMemory(trajectories, options = {}) {
  const maxEntries = options.maxEntries ?? 20;
  const entries = [];
  for (const trajectory of trajectories) {
    for (const label of allLabels(trajectory)) {
      const instruction = instructionFromLabel(trajectory, label);
      if (!instruction) continue;
      entries.push({
        instruction,
        rationale: label.reason ?? `${label.kind} label from ${label.source}`,
        weight: weightForLabel(label),
        sourceTrajectoryId: trajectory.id,
        sourceLabelId: label.id,
        category: label.kind
      });
    }
  }
  const byInstruction = /* @__PURE__ */ new Map();
  for (const entry of entries) {
    const key = entry.instruction.toLowerCase().replace(/\s+/g, " ").trim();
    const existing = byInstruction.get(key);
    if (!existing || entry.weight > existing.weight) byInstruction.set(key, entry);
  }
  return [...byInstruction.values()].sort((a, b) => b.weight - a.weight).slice(0, maxEntries);
}
function renderPreferenceMemoryMarkdown(entries) {
  const lines = ["# Preference Memory", ""];
  for (const entry of entries) {
    lines.push(`- ${entry.instruction}`);
    lines.push(`  Rationale: ${entry.rationale}`);
    lines.push(`  Source: ${entry.sourceTrajectoryId}`);
    lines.push("");
  }
  return `${lines.join("\n").trim()}
`;
}
function serializeFeedbackTrajectoriesJsonl(trajectories) {
  return `${trajectories.slice().sort((a, b) => a.id.localeCompare(b.id)).map((trajectory) => JSON.stringify(canonicalize(trajectory))).join("\n")}
`;
}
function parseFeedbackTrajectoriesJsonl(jsonl) {
  const trajectories = [];
  for (const line of jsonl.split("\n")) {
    if (!line.trim()) continue;
    trajectories.push(JSON.parse(line));
  }
  return trajectories;
}
function controlRunToFeedbackTrajectory(run, options = {}) {
  const createdAt = options.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
  const trajectoryId = run.runId ?? `ft_control_${stableHash(`${run.intent}|${createdAt}`).toString(16)}`;
  return createFeedbackTrajectory({
    id: trajectoryId,
    projectId: options.projectId,
    scenarioId: options.scenarioId,
    task: { intent: run.intent },
    createdAt,
    attempts: run.steps.map((step) => ({
      id: `${trajectoryId}_step_${step.index}`,
      stepIndex: step.index,
      artifactType: options.artifactType ?? "action",
      artifact: options.artifactFromStep?.(step) ?? step.actionOutcome?.result ?? step.decision,
      proposedAction: options.proposedActionFromStep?.(step),
      evals: step.evalsAfter,
      createdAt: step.startedAt,
      metadata: {
        decision: step.decision,
        actionOutcome: step.actionOutcome
      }
    })),
    labels: [
      {
        source: "system",
        kind: run.pass ? "approve" : "reject",
        value: run.pass,
        reason: run.reason,
        severity: run.pass ? "info" : "error",
        createdAt
      }
    ],
    outcome: {
      success: run.pass,
      score: run.score,
      costUsd: run.spentCostUsd,
      detail: run.reason,
      observedAt: createdAt,
      metadata: {
        stoppedBy: run.stoppedBy,
        failureClass: run.failureClass
      }
    }
  });
}
function allLabels(trajectory) {
  const labels = [
    ...trajectory.labels,
    ...trajectory.attempts.flatMap((attempt) => attempt.feedback ?? [])
  ];
  const seen = /* @__PURE__ */ new Set();
  return labels.filter((label) => {
    const key = label.id ?? `${label.source}|${label.kind}|${label.createdAt}|${JSON.stringify(label.value)}`;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}
function scoreFromLabels(labels) {
  if (!labels.length) return void 0;
  const scored = labels.map((label) => {
    if (label.kind === "approve" || label.kind === "select") return 1;
    if (label.kind === "reject" || label.kind === "policy_block") return 0;
    if (label.kind === "rate" && typeof label.value === "number")
      return Math.max(0, Math.min(1, label.value));
    return void 0;
  }).filter((value) => typeof value === "number");
  if (!scored.length) return void 0;
  return Math.round(scored.reduce((sum, value) => sum + value, 0) / scored.length * 1e3) / 1e3;
}
function instructionFromLabel(trajectory, label) {
  if (label.kind === "reject" && label.reason)
    return `Avoid outputs like "${compact(trajectory.task.intent, 80)}" when: ${label.reason}`;
  if (label.kind === "revision_request" && label.reason)
    return `Revise similar work by applying: ${label.reason}`;
  if (label.kind === "select" && label.reason)
    return `Prefer selected options for "${compact(trajectory.task.intent, 80)}" because: ${label.reason}`;
  if (label.kind === "approve" && label.reason)
    return `Repeat the pattern approved for "${compact(trajectory.task.intent, 80)}": ${label.reason}`;
  if (label.kind === "comment" && label.reason) return label.reason;
  return void 0;
}
function weightForLabel(label) {
  const severity = label.severity === "critical" ? 4 : label.severity === "error" ? 3 : label.severity === "warning" ? 2 : 1;
  const source = label.source === "user" ? 3 : label.source === "metric" || label.source === "environment" ? 2 : 1;
  return severity * source;
}
function matchesFilter(trajectory, filter) {
  if (filter.projectId && trajectory.projectId !== filter.projectId) return false;
  if (filter.scenarioId && trajectory.scenarioId !== filter.scenarioId) return false;
  if (filter.split && trajectory.split !== filter.split) return false;
  if (filter.tag) {
    const [key, value] = filter.tag;
    if (trajectory.tags?.[key] !== value) return false;
  }
  return true;
}
function cloneTrajectory(trajectory) {
  return JSON.parse(JSON.stringify(trajectory));
}
function compact(value, max) {
  const normalized = value.replace(/\s+/g, " ").trim();
  return normalized.length > max ? `${normalized.slice(0, max).trim()}...` : normalized;
}
function stableHash(input) {
  let hash = 2166136261;
  for (let i = 0; i < input.length; i += 1) {
    hash ^= input.charCodeAt(i);
    hash = Math.imul(hash, 16777619);
  }
  return hash >>> 0;
}
function canonicalize(value) {
  if (value === null || typeof value !== "object") return value;
  if (Array.isArray(value)) return value.map(canonicalize);
  const out = {};
  for (const key of Object.keys(value).sort()) {
    out[key] = canonicalize(value[key]);
  }
  return out;
}

// src/held-out-gate.ts
var HeldOutGate = class {
  minProductiveRuns;
  pairedDeltaThreshold;
  overfitGapThreshold;
  baselineKey;
  confidence;
  resamples;
  seed;
  constructor(config) {
    if (!config.baselineKey) {
      throw new Error("HeldOutGate: baselineKey is required");
    }
    this.minProductiveRuns = config.minProductiveRuns ?? 3;
    this.pairedDeltaThreshold = config.pairedDeltaThreshold ?? 0;
    this.overfitGapThreshold = config.overfitGapThreshold ?? 0.15;
    this.baselineKey = config.baselineKey;
    this.confidence = config.confidence ?? 0.95;
    this.resamples = config.bootstrapResamples ?? 2e3;
    this.seed = config.seed;
  }
  /** Decide whether `candidate` should replace `baseline`. Pairing
   *  is by (experimentId, seed) — identical experiment + seed pairs
   *  the candidate run with the matching baseline run. Pairs without
   *  a holdout score on both sides are dropped. */
  evaluate(candidate, baseline) {
    const candidateId = inferCandidateId(candidate, this.baselineKey);
    const baselineId = this.baselineKey;
    const baselineHoldoutByKey = indexHoldoutByKey(baseline);
    const beforeHoldout = [];
    const afterHoldout = [];
    for (const run of candidate) {
      if (run.splitTag !== "holdout") continue;
      if (run.outcome.holdoutScore === void 0) continue;
      const key = pairKey(run);
      const counterpart = baselineHoldoutByKey.get(key);
      if (counterpart === void 0) continue;
      beforeHoldout.push(counterpart);
      afterHoldout.push(run.outcome.holdoutScore);
    }
    const productiveRuns = beforeHoldout.length;
    const candidateSearchMean = mean(scores(candidate, "searchScore", "search"));
    const candidateHoldoutMean = mean(scores(candidate, "holdoutScore", "holdout"));
    const baselineSearchMean = mean(scores(baseline, "searchScore", "search"));
    const baselineHoldoutMean = mean(scores(baseline, "holdoutScore", "holdout"));
    const overfitGap = safeDiff(candidateSearchMean, candidateHoldoutMean);
    const baselineOverfitGap = safeDiff(baselineSearchMean, baselineHoldoutMean);
    if (productiveRuns < this.minProductiveRuns) {
      return {
        promote: false,
        candidateId,
        baselineId,
        evidence: {
          productiveRuns,
          medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : 0,
          pairedCI: { low: 0, high: 0 },
          pairedPValue: 1,
          searchScore: candidateSearchMean,
          holdoutScore: candidateHoldoutMean,
          overfitGap,
          baselineOverfitGap
        },
        reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,
        rejectionCode: "few_runs"
      };
    }
    const ci = pairedBootstrap(beforeHoldout, afterHoldout, {
      confidence: this.confidence,
      resamples: this.resamples,
      statistic: "median",
      seed: this.seed
    });
    const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout);
    const evidence = {
      productiveRuns,
      medianPairedDelta: ci.median,
      pairedCI: { low: ci.low, high: ci.high },
      pairedPValue: wilcoxon.p,
      searchScore: candidateSearchMean,
      holdoutScore: candidateHoldoutMean,
      overfitGap,
      baselineOverfitGap
    };
    if (!(ci.low > this.pairedDeltaThreshold)) {
      return {
        promote: false,
        candidateId,
        baselineId,
        evidence,
        reason: `negative_delta: paired holdout median \u0394=${fmt(ci.median)} CI=[${fmt(ci.low)}, ${fmt(ci.high)}] does not clear threshold ${fmt(this.pairedDeltaThreshold)}`,
        rejectionCode: "negative_delta"
      };
    }
    if (Number.isFinite(overfitGap) && Number.isFinite(baselineOverfitGap) && overfitGap > baselineOverfitGap + this.overfitGapThreshold) {
      return {
        promote: false,
        candidateId,
        baselineId,
        evidence,
        reason: `overfit_gap: candidate gap=${fmt(overfitGap)} exceeds baseline gap=${fmt(baselineOverfitGap)} by more than ${fmt(this.overfitGapThreshold)}`,
        rejectionCode: "overfit_gap"
      };
    }
    return {
      promote: true,
      candidateId,
      baselineId,
      evidence,
      reason: `promote: paired holdout median \u0394=${fmt(ci.median)} CI=[${fmt(ci.low)}, ${fmt(ci.high)}] over ${productiveRuns} pairs; overfit gap candidate=${fmt(overfitGap)} vs baseline=${fmt(baselineOverfitGap)}`,
      rejectionCode: null
    };
  }
};
function inferCandidateId(candidate, baselineKey) {
  for (const run of candidate) {
    if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId;
  }
  return candidate[0]?.candidateId ?? "(unknown candidate)";
}
function indexHoldoutByKey(runs) {
  const out = /* @__PURE__ */ new Map();
  for (const r of runs) {
    if (r.splitTag !== "holdout") continue;
    if (r.outcome.holdoutScore === void 0) continue;
    out.set(pairKey(r), r.outcome.holdoutScore);
  }
  return out;
}
function pairKey(r) {
  return `${r.experimentId}::${r.seed}`;
}
function scores(runs, field, splitFilter) {
  const out = [];
  for (const r of runs) {
    if (r.splitTag !== splitFilter) continue;
    const v = r.outcome[field];
    if (typeof v === "number" && Number.isFinite(v)) out.push(v);
  }
  return out;
}
function mean(xs) {
  if (xs.length === 0) return Number.NaN;
  return xs.reduce((s, x) => s + x, 0) / xs.length;
}
function safeDiff(a, b) {
  if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.NaN;
  return a - b;
}
function medianDelta(before, after) {
  const ds = before.map((b, i) => after[i] - b).sort((x, y) => x - y);
  if (ds.length === 0) return 0;
  const mid = Math.floor(ds.length / 2);
  return ds.length % 2 === 0 ? (ds[mid - 1] + ds[mid]) / 2 : ds[mid];
}
function fmt(x) {
  if (!Number.isFinite(x)) return String(x);
  return x.toFixed(4);
}

// src/pareto.ts
function dominates(a, b, objectives) {
  let strictlyBetter = false;
  for (const obj of objectives) {
    const av = obj.value(a);
    const bv = obj.value(b);
    if (!Number.isFinite(av) || !Number.isFinite(bv)) return false;
    const aIsBetter = obj.direction === "maximize" ? av > bv : av < bv;
    const aIsWorse = obj.direction === "maximize" ? av < bv : av > bv;
    if (aIsWorse) return false;
    if (aIsBetter) strictlyBetter = true;
  }
  return strictlyBetter;
}
function paretoFrontier(candidates, objectives) {
  if (objectives.length === 0) {
    throw new Error("paretoFrontier: at least 1 objective required");
  }
  const valid = candidates.filter((c) => objectives.every((o) => Number.isFinite(o.value(c))));
  const frontier = [];
  const dominated = [];
  for (const c of valid) {
    const isDominated = valid.some((other) => other !== c && dominates(other, c, objectives));
    if (isDominated) dominated.push(c);
    else frontier.push(c);
  }
  const dominanceMap = frontier.map((d) => ({
    dominator: d,
    dominated: dominated.filter((x) => dominates(d, x, objectives))
  }));
  return { frontier, dominated, dominanceMap };
}
function scalarScore(candidates, objectives, options = {}) {
  if (candidates.length === 0) return [];
  const weights = options.weights ?? {};
  const totalWeight = objectives.reduce((s, o) => s + (weights[o.name] ?? 1), 0);
  const ranges = objectives.map((obj) => {
    const values = candidates.map((c) => obj.value(c)).filter((v) => Number.isFinite(v));
    if (values.length === 0) return { min: 0, max: 1 };
    const min = Math.min(...values);
    const max = Math.max(...values);
    return { min, max: max === min ? min + 1 : max };
  });
  return candidates.map((c) => {
    let score = 0;
    objectives.forEach((obj, i) => {
      const v = obj.value(c);
      if (!Number.isFinite(v)) return;
      const { min, max } = ranges[i];
      const normalised = (v - min) / (max - min);
      const directional = obj.direction === "maximize" ? normalised : 1 - normalised;
      const weight = (weights[obj.name] ?? 1) / totalWeight;
      score += directional * weight;
    });
    return { candidate: c, score };
  });
}
function crowdingDistance(candidates, objectives) {
  const distances = new Map(candidates.map((c) => [c, 0]));
  for (const obj of objectives) {
    const sorted = [...candidates].sort((a, b) => obj.value(a) - obj.value(b));
    const min = obj.value(sorted[0]);
    const max = obj.value(sorted[sorted.length - 1]);
    const range = max - min || 1;
    distances.set(sorted[0], Infinity);
    distances.set(sorted[sorted.length - 1], Infinity);
    for (let i = 1; i < sorted.length - 1; i++) {
      const prev = obj.value(sorted[i - 1]);
      const next = obj.value(sorted[i + 1]);
      const current = distances.get(sorted[i]);
      if (current === Infinity) continue;
      distances.set(sorted[i], current + (next - prev) / range);
    }
  }
  return candidates.map((c) => ({ candidate: c, distance: distances.get(c) ?? 0 }));
}
function paretoFrontierWithCrowding(candidates, objectives) {
  const { frontier } = paretoFrontier(candidates, objectives);
  if (frontier.length === 0) return [];
  const distances = crowdingDistance(frontier, objectives);
  return distances.sort((a, b) => b.distance - a.distance);
}

// src/prompt-evolution.ts
var InMemoryTrialCache = class {
  store = /* @__PURE__ */ new Map();
  get(key) {
    return this.store.get(key);
  }
  set(key, value) {
    this.store.set(key, value);
  }
  size() {
    return this.store.size;
  }
  clear() {
    this.store.clear();
  }
};
async function runPromptEvolution(config) {
  const generations = [];
  let population = [...config.seedVariants];
  let bestVariant = population[0];
  let bestAggregate = null;
  for (let generation = 0; generation < config.generations; generation++) {
    config.onProgress?.({ type: "generation-start", generation, populationSize: population.length });
    const trials = await scorePopulation(population, config, generation);
    const aggregates = aggregateTrials(population, config.scenarioIds, trials);
    const front = paretoFrontierWithCrowding(aggregates, config.objectives);
    const frontIds = new Set(front.map((c) => c.candidate.variantId));
    const scored = scalarScore(aggregates, config.objectives, { weights: config.scalarWeights });
    scored.sort((a, b) => b.score - a.score);
    const winnerId = scored[0]?.candidate.variantId ?? aggregates[0]?.variantId ?? population[0].id;
    const report = {
      runId: config.runId,
      target: config.target,
      generation,
      variants: population,
      aggregates,
      paretoFrontIds: front.map((c) => c.candidate.variantId),
      winnerId,
      trials
    };
    generations.push(report);
    config.onProgress?.({ type: "generation-complete", report });
    const winnerAgg = aggregates.find((a) => a.variantId === winnerId);
    if (winnerAgg) {
      const winner = population.find((v) => v.id === winnerId);
      if (winner) bestVariant = winner;
      bestAggregate = winnerAgg;
    }
    if (config.earlyStopOnNoImprovement !== false && generations.length >= 2) {
      const prev = generations[generations.length - 2];
      const noChange = prev.winnerId === winnerId && samePopulation(prev.paretoFrontIds, [...frontIds]);
      if (noChange) {
        config.onProgress?.({
          type: "converged",
          generation,
          reason: "no improvement vs previous generation"
        });
        break;
      }
    }
    if (generation === config.generations - 1) break;
    population = await nextPopulation(population, aggregates, trials, front, config, generation + 1);
  }
  return {
    runId: config.runId,
    target: config.target,
    generations,
    bestVariant,
    bestAggregate: bestAggregate ?? aggregateTrials(population, config.scenarioIds, []).find(
      (a) => a.variantId === bestVariant.id
    )
  };
}
async function scorePopulation(population, config, generation) {
  const jobs = [];
  for (const variant of population) {
    for (const scenarioId of config.scenarioIds) {
      for (let rep = 0; rep < config.reps; rep++) {
        jobs.push(async () => {
          const cacheKey = `${variant.id}|${scenarioId}|${rep}`;
          const cached = config.cache?.get(cacheKey);
          if (cached) {
            config.onProgress?.({
              type: "trial-complete",
              generation,
              variantId: variant.id,
              scenarioId,
              rep,
              ok: cached.ok,
              score: cached.score,
              cached: true
            });
            return cached;
          }
          const result = await config.scoreAdapter.score({ variant, scenarioId, rep });
          config.cache?.set(cacheKey, result);
          config.onProgress?.({
            type: "trial-complete",
            generation,
            variantId: variant.id,
            scenarioId,
            rep,
            ok: result.ok,
            score: result.score,
            cached: false
          });
          return result;
        });
      }
    }
  }
  return runWithConcurrency(jobs, config.scoreConcurrency);
}
async function runWithConcurrency(jobs, concurrency) {
  const results = new Array(jobs.length);
  const limit = Math.max(1, concurrency);
  let next = 0;
  async function worker() {
    while (true) {
      const i = next++;
      if (i >= jobs.length) return;
      results[i] = await jobs[i]();
    }
  }
  await Promise.all(Array.from({ length: limit }, () => worker()));
  return results;
}
function aggregateTrials(population, scenarioIds, trials) {
  return population.map((variant) => {
    const variantTrials = trials.filter((t) => t.variantId === variant.id);
    const scenarios = scenarioIds.map((sid) => {
      const scenarioTrials = variantTrials.filter((t) => t.scenarioId === sid);
      const okTrials = scenarioTrials.filter((t) => t.ok);
      const gradedTrials = scenarioTrials.filter((t) => !t.error);
      const metrics = aggregateMetrics(gradedTrials.map((t) => t.metrics ?? {}));
      return {
        variantId: variant.id,
        scenarioId: sid,
        meanScore: mean2(gradedTrials.map((t) => t.score)),
        meanCost: mean2(gradedTrials.map((t) => t.cost ?? 0)),
        meanDurationMs: mean2(gradedTrials.map((t) => t.durationMs ?? 0)),
        okRate: scenarioTrials.length === 0 ? 0 : okTrials.length / scenarioTrials.length,
        trials: scenarioTrials.length,
        metrics
      };
    });
    return {
      variantId: variant.id,
      meanScore: mean2(scenarios.map((s) => s.meanScore)),
      meanCost: mean2(scenarios.map((s) => s.meanCost)),
      meanDurationMs: mean2(scenarios.map((s) => s.meanDurationMs)),
      okRate: mean2(scenarios.map((s) => s.okRate)),
      scenarios,
      metrics: aggregateMetrics(scenarios.map((s) => s.metrics))
    };
  });
}
function aggregateMetrics(rows) {
  const buckets = /* @__PURE__ */ new Map();
  for (const row of rows) {
    for (const [k, v] of Object.entries(row)) {
      if (!Number.isFinite(v)) continue;
      const list = buckets.get(k) ?? [];
      list.push(v);
      buckets.set(k, list);
    }
  }
  const out = {};
  for (const [k, list] of buckets) out[k] = mean2(list);
  return out;
}
function mean2(xs) {
  if (xs.length === 0) return 0;
  return xs.reduce((a, b) => a + b, 0) / xs.length;
}
async function nextPopulation(current, aggregates, trials, front, config, nextGeneration) {
  const survivorIds = new Set(front.map((c) => c.candidate.variantId));
  const survivors = current.filter((v) => survivorIds.has(v.id));
  const ranked = scalarScore(aggregates, config.objectives, { weights: config.scalarWeights }).sort(
    (a, b) => b.score - a.score
  );
  const parentId = ranked[0]?.candidate.variantId ?? current[0].id;
  const parent = current.find((v) => v.id === parentId) ?? current[0];
  const parentAggregate = aggregates.find((a) => a.variantId === parent.id) ?? aggregates[0];
  const topTrials = topKTrialsByScore(trials, parent.id, 3);
  const bottomTrials = bottomKTrialsByScore(trials, parent.id, 3);
  const childCount = Math.max(0, config.populationSize - survivors.length);
  let children = [];
  if (childCount > 0) {
    children = await config.mutateAdapter.mutate({
      parent,
      parentAggregate,
      topTrials,
      bottomTrials,
      childCount,
      generation: nextGeneration
    });
    children = children.slice(0, childCount).map((c) => ({ ...c, generation: nextGeneration, parentId: parent.id }));
  }
  return [...survivors, ...children];
}
function topKTrialsByScore(trials, variantId, k) {
  return trials.filter((t) => t.variantId === variantId && t.ok).sort((a, b) => b.score - a.score).slice(0, k);
}
function bottomKTrialsByScore(trials, variantId, k) {
  return trials.filter((t) => t.variantId === variantId && t.ok).sort((a, b) => a.score - b.score).slice(0, k);
}
function samePopulation(a, b) {
  if (a.length !== b.length) return false;
  const setA = new Set(a);
  return b.every((id) => setA.has(id));
}

// src/multi-shot-optimization.ts
async function runMultiShotOptimization(config) {
  validateConfig(config);
  const scoreAdapter = {
    score: (args) => scoreOne(config, args.variant, args.scenarioId, args.rep, "search")
  };
  const evolution = await runPromptEvolution({
    runId: config.runId,
    target: config.target,
    seedVariants: config.seedVariants,
    scenarioIds: config.searchScenarioIds,
    reps: config.reps,
    generations: config.generations,
    populationSize: config.populationSize,
    scoreConcurrency: config.scoreConcurrency ?? 1,
    scoreAdapter,
    mutateAdapter: {
      mutate: (args) => config.mutateAdapter.mutate({
        ...args,
        topTrials: args.topTrials,
        bottomTrials: args.bottomTrials
      })
    },
    objectives: config.objectives ?? defaultMultiShotObjectives(),
    scalarWeights: config.scalarWeights,
    earlyStopOnNoImprovement: config.earlyStopOnNoImprovement,
    cache: config.cache,
    onProgress: config.onProgress
  });
  let gate = null;
  const baseline = config.seedVariants[0];
  let promotedVariant = evolution.bestVariant;
  let promotedAggregate = evolution.bestAggregate;
  if (config.gate && evolution.bestVariant.id !== baseline.id) {
    gate = await evaluateMultiShotGate(config, baseline, evolution.bestVariant);
    if (!gate.decision.promote) {
      promotedVariant = baseline;
      promotedAggregate = aggregateFor(evolution, baseline.id);
    }
  }
  return {
    evolution,
    searchBestVariant: evolution.bestVariant,
    searchBestAggregate: evolution.bestAggregate,
    promotedVariant,
    promotedAggregate,
    gate
  };
}
function defaultMultiShotObjectives() {
  return [
    { name: "score", direction: "maximize", value: (a) => a.meanScore },
    { name: "cost", direction: "minimize", value: (a) => a.meanCost }
  ];
}
function trialTraceFromMultiShotTrial(trial) {
  return {
    id: `${trial.variantId}/${trial.scenarioId}/r${trial.rep}`,
    score: trial.score,
    inputName: trial.scenarioId,
    expectations: (trial.asi ?? []).map((item, i) => ({
      id: item.expectationId ?? `asi-${i}`,
      phrase: item.message,
      matched: item.matched ?? false
    })),
    emitted: trial.emitted ?? traceExcerpt(trial.trace),
    metrics: trial.metrics
  };
}
async function evaluateMultiShotGate(config, baseline, candidate) {
  const gateConfig = config.gate;
  const reps = gateConfig.reps ?? config.reps;
  const candidateRuns = [];
  const baselineRuns = [];
  const searchIds = gateConfig.searchScenarioIds ?? config.searchScenarioIds;
  for (const scenarioId of searchIds) {
    for (let rep = 0; rep < reps; rep++) {
      const seed = seedFor(config, scenarioId, rep);
      const baseTrial = await scoreOne(config, baseline, scenarioId, rep, "search");
      const candTrial = await scoreOne(config, candidate, scenarioId, rep, "search");
      baselineRuns.push(
        toValidatedRecord(config, baseline, scenarioId, rep, "search", seed, baseTrial)
      );
      candidateRuns.push(
        toValidatedRecord(config, candidate, scenarioId, rep, "search", seed, candTrial)
      );
    }
  }
  for (const scenarioId of gateConfig.holdoutScenarioIds) {
    for (let rep = 0; rep < reps; rep++) {
      const seed = seedFor(config, scenarioId, rep);
      const baseTrial = await scoreOne(config, baseline, scenarioId, rep, "holdout");
      const candTrial = await scoreOne(config, candidate, scenarioId, rep, "holdout");
      baselineRuns.push(
        toValidatedRecord(config, baseline, scenarioId, rep, "holdout", seed, baseTrial)
      );
      candidateRuns.push(
        toValidatedRecord(config, candidate, scenarioId, rep, "holdout", seed, candTrial)
      );
    }
  }
  const decision = new HeldOutGate(gateConfig.gate).evaluate(candidateRuns, baselineRuns);
  return { decision, candidateRuns, baselineRuns };
}
async function scoreOne(config, variant, scenarioId, rep, split) {
  const seed = seedFor(config, scenarioId, rep);
  const input = { variant, scenarioId, rep, split, seed };
  try {
    const run = await config.runner.run(input);
    const scored = await config.scorer.score({ ...input, run });
    const asi = scored.asi ?? [];
    return {
      variantId: variant.id,
      scenarioId,
      rep,
      ok: scored.ok ?? true,
      score: clamp01(scored.score),
      cost: scored.costUsd ?? run.costUsd ?? 0,
      durationMs: scored.durationMs ?? run.durationMs ?? 0,
      metrics: {
        ...numericMetrics(scored.metrics),
        ...asiMetrics(asi)
      },
      split,
      seed,
      trace: run.trace,
      asi,
      emitted: scored.emitted ?? traceExcerpt(run.trace),
      metadata: scored.metadata
    };
  } catch (err) {
    return {
      variantId: variant.id,
      scenarioId,
      rep,
      ok: false,
      score: 0,
      cost: 0,
      durationMs: 0,
      metrics: { error: 1 },
      error: err instanceof Error ? err.message : String(err),
      split,
      seed,
      asi: [
        {
          severity: "critical",
          message: err instanceof Error ? err.message : String(err),
          responsibleSurface: config.target
        }
      ],
      emitted: ""
    };
  }
}
function toValidatedRecord(config, variant, scenarioId, rep, split, seed, trial) {
  const record = config.gate.toRunRecord({ variant, scenarioId, rep, split, seed, trial });
  return validateRunRecord(record);
}
function validateConfig(config) {
  if (!config.runId.trim()) throw new Error("runMultiShotOptimization: runId must not be empty");
  if (!config.target.trim()) throw new Error("runMultiShotOptimization: target must not be empty");
  if (config.seedVariants.length === 0) {
    throw new Error("runMultiShotOptimization: seedVariants must not be empty");
  }
  if (config.searchScenarioIds.length === 0) {
    throw new Error("runMultiShotOptimization: searchScenarioIds must not be empty");
  }
  requirePositiveInteger(config.reps, "reps");
  requirePositiveInteger(config.generations, "generations");
  requirePositiveInteger(config.populationSize, "populationSize");
  if (config.scoreConcurrency !== void 0)
    requirePositiveInteger(config.scoreConcurrency, "scoreConcurrency");
  if (config.populationSize < config.seedVariants.length) {
    throw new Error("runMultiShotOptimization: populationSize must be >= seedVariants.length");
  }
  assertUnique(
    config.seedVariants.map((v) => v.id),
    "seedVariants.id"
  );
  assertUnique(config.searchScenarioIds, "searchScenarioIds");
  if (config.gate) {
    if (config.gate.holdoutScenarioIds.length === 0) {
      throw new Error("runMultiShotOptimization: gate.holdoutScenarioIds must not be empty");
    }
    if (config.gate.reps !== void 0) requirePositiveInteger(config.gate.reps, "gate.reps");
    assertUnique(config.gate.holdoutScenarioIds, "gate.holdoutScenarioIds");
    if (config.gate.searchScenarioIds)
      assertUnique(config.gate.searchScenarioIds, "gate.searchScenarioIds");
    const searchIds = new Set(config.searchScenarioIds);
    for (const id of config.gate.holdoutScenarioIds) {
      if (searchIds.has(id)) {
        throw new Error(
          `runMultiShotOptimization: holdout scenario "${id}" also appears in searchScenarioIds`
        );
      }
    }
    const baselineId = config.seedVariants[0].id;
    if (config.gate.gate.baselineKey !== baselineId) {
      throw new Error(
        `runMultiShotOptimization: gate.gate.baselineKey must match first seed variant id "${baselineId}"`
      );
    }
  }
}
function requirePositiveInteger(value, name) {
  if (!Number.isInteger(value) || value <= 0) {
    throw new Error(`runMultiShotOptimization: ${name} must be a positive integer`);
  }
}
function assertUnique(values, name) {
  const seen = /* @__PURE__ */ new Set();
  for (const value of values) {
    if (!value.trim())
      throw new Error(`runMultiShotOptimization: ${name} must not contain empty values`);
    if (seen.has(value)) throw new Error(`runMultiShotOptimization: duplicate ${name} "${value}"`);
    seen.add(value);
  }
}
function aggregateFor(evolution, variantId) {
  const final = evolution.generations[evolution.generations.length - 1];
  const aggregate = final?.aggregates.find((a) => a.variantId === variantId);
  if (!aggregate) {
    throw new Error(`runMultiShotOptimization: missing aggregate for variant "${variantId}"`);
  }
  return aggregate;
}
function seedFor(config, scenarioId, rep) {
  const base = config.seedBase ?? 0;
  return (base + stableHash2(`${scenarioId}${rep}`)) % Number.MAX_SAFE_INTEGER;
}
function stableHash2(input) {
  let h = 2166136261;
  for (let i = 0; i < input.length; i++) {
    h ^= input.charCodeAt(i);
    h = Math.imul(h, 16777619);
  }
  return h >>> 0;
}
function clamp01(n) {
  if (!Number.isFinite(n)) return 0;
  return Math.max(0, Math.min(1, n));
}
function numericMetrics(metrics) {
  const out = {};
  for (const [k, v] of Object.entries(metrics ?? {})) {
    if (Number.isFinite(v)) out[k] = v;
  }
  return out;
}
function asiMetrics(asi) {
  const out = { asi: asi.length };
  for (const item of asi.slice(0, 1e3)) {
    const sev = normalizeSeverity(item.severity);
    out[`asi.${sev}`] = (out[`asi.${sev}`] ?? 0) + 1;
    if (item.responsibleSurface) {
      const key = `surface.${metricKeySegment(item.responsibleSurface)}`;
      out[key] = (out[key] ?? 0) + 1;
    }
  }
  return out;
}
function normalizeSeverity(severity) {
  if (severity === "info" || severity === "warning" || severity === "error" || severity === "critical") {
    return severity;
  }
  return "error";
}
function metricKeySegment(raw) {
  return raw.trim().replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 80) || "unknown";
}
function traceExcerpt(trace) {
  if (!trace) return void 0;
  if (typeof trace.output === "string") return trace.output;
  if (trace.transcript) return trace.transcript;
  if (trace.turns) {
    try {
      const clipped = trace.turns.slice(0, 20);
      const suffix = trace.turns.length > clipped.length ? ` ... ${trace.turns.length - clipped.length} more turn(s)` : "";
      return `${JSON.stringify(clipped).slice(0, 2e3)}${suffix}`;
    } catch {
      return "[unserializable trace turns]";
    }
  }
  return void 0;
}

// src/reflective-mutation.ts
var DEFAULT_MUTATION_PRIMITIVES = [
  'Strengthen an imperative ("should" \u2192 "must")',
  "Add a concrete example pulled from a missed-golden phrase",
  "Remove a redundant rule that did not improve recall",
  'Add a counterfactual ("if X is missing, the score is capped at Y")',
  "Reorder sections so the highest-impact rule is first",
  "Replace abstract language with a domain-specific noun the trial misses"
];
function buildReflectionPrompt(ctx) {
  const primitives = ctx.mutationPrimitives ?? DEFAULT_MUTATION_PRIMITIVES;
  const sections = [];
  sections.push(`# Mutation target: ${ctx.target}`);
  sections.push("");
  sections.push(
    `You are tuning the prompt component named \`${ctx.target}\`. The current variant is shown below; you have ${ctx.topTrials.length} top trials and ${ctx.bottomTrials.length} bottom trials as evidence. Propose ${ctx.childCount} mutation${ctx.childCount === 1 ? "" : "s"} that fix specific weaknesses visible in the bottom trials. Avoid blank rephrasings.`
  );
  sections.push("");
  sections.push("## Current variant");
  sections.push("```json");
  sections.push(JSON.stringify(ctx.parentPayload, null, 2));
  sections.push("```");
  sections.push("");
  if (ctx.bottomTrials.length > 0) {
    sections.push("## Failures (bottom trials) \u2014 what went wrong");
    sections.push("");
    for (const trial of ctx.bottomTrials) {
      sections.push(
        `### Trial \`${trial.id}\` \u2014 score ${trial.score.toFixed(2)}${trial.inputName ? ` (${trial.inputName})` : ""}`
      );
      const missed = (trial.expectations ?? []).filter((e) => !e.matched);
      if (missed.length > 0) {
        sections.push("");
        sections.push("**Missed expectations:**");
        for (const m of missed) {
          sections.push(`- \`${m.id}\`: should match phrase \`${quote(m.phrase)}\``);
        }
      }
      if (trial.emitted) {
        sections.push("");
        sections.push("**What the agent emitted:**");
        sections.push("```");
        sections.push(truncate(trial.emitted, 600));
        sections.push("```");
      }
      sections.push("");
    }
  }
  if (ctx.topTrials.length > 0) {
    sections.push("## Successes (top trials) \u2014 what to preserve");
    sections.push("");
    for (const trial of ctx.topTrials) {
      sections.push(
        `- \`${trial.id}\`: score ${trial.score.toFixed(2)}${trial.inputName ? ` (${trial.inputName})` : ""}`
      );
    }
    sections.push("");
  }
  sections.push("## Allowed mutation primitives");
  sections.push("");
  for (const p of primitives) sections.push(`- ${p}`);
  sections.push("");
  sections.push("## Output schema");
  sections.push("");
  sections.push("Respond with a JSON object \u2014 no prose, no markdown fences:");
  sections.push("```json");
  sections.push(
    JSON.stringify(
      {
        proposals: [
          {
            label: "<short label, \u2264 40 chars>",
            rationale: "<which failure this targets and which primitive you used>",
            payload: "<full payload of the new variant \u2014 same shape as the current variant>"
          }
        ]
      },
      null,
      2
    )
  );
  sections.push("```");
  return sections.join("\n");
}
function truncate(s, max) {
  if (s.length <= max) return s;
  return `${s.slice(0, max)}\u2026 [truncated]`;
}
function quote(s) {
  return s.replace(/`/g, "\\`");
}
function autoCloseTruncatedJson(raw) {
  const stack = [];
  let inString = false;
  let escaped = false;
  for (const c of raw) {
    if (escaped) {
      escaped = false;
      continue;
    }
    if (inString) {
      if (c === "\\") {
        escaped = true;
        continue;
      }
      if (c === '"') {
        inString = false;
        continue;
      }
      continue;
    }
    if (c === '"') {
      inString = true;
      continue;
    }
    if (c === "{" || c === "[") stack.push(c);
    else if (c === "}") {
      if (stack.pop() !== "{") return null;
    } else if (c === "]") {
      if (stack.pop() !== "[") return null;
    }
  }
  if (stack.length === 0 && !inString) return raw;
  let suffix = "";
  if (inString) suffix += '"';
  while (stack.length > 0) {
    const opener = stack.pop();
    suffix += opener === "{" ? "}" : "]";
  }
  return raw + suffix;
}
function parseReflectionResponse(raw, maxProposals) {
  let text = raw.trim();
  if (text.startsWith("```")) text = text.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "");
  let parsed = null;
  const objectStart = text.indexOf("{");
  const objectEnd = text.lastIndexOf("}");
  const arrayStart = text.indexOf("[");
  const arrayEnd = text.lastIndexOf("]");
  const tryObjectFirst = objectStart >= 0 && (arrayStart < 0 || objectStart < arrayStart);
  const candidates = [];
  if (tryObjectFirst) {
    if (objectStart >= 0 && objectEnd > objectStart)
      candidates.push(text.slice(objectStart, objectEnd + 1));
    if (arrayStart >= 0 && arrayEnd > arrayStart)
      candidates.push(text.slice(arrayStart, arrayEnd + 1));
  } else {
    if (arrayStart >= 0 && arrayEnd > arrayStart)
      candidates.push(text.slice(arrayStart, arrayEnd + 1));
    if (objectStart >= 0 && objectEnd > objectStart)
      candidates.push(text.slice(objectStart, objectEnd + 1));
  }
  for (const slice of candidates) {
    try {
      parsed = JSON.parse(slice);
      break;
    } catch {
    }
  }
  if (parsed == null) {
    for (const slice of candidates) {
      const closed = autoCloseTruncatedJson(slice);
      if (closed != null && closed !== slice) {
        try {
          parsed = JSON.parse(closed);
          break;
        } catch {
        }
      }
    }
  }
  if (parsed == null) return [];
  let proposalsRaw;
  if (Array.isArray(parsed)) {
    proposalsRaw = parsed;
  } else if (parsed && typeof parsed === "object") {
    proposalsRaw = parsed.proposals;
  }
  if (!Array.isArray(proposalsRaw)) return [];
  const out = [];
  for (const p of proposalsRaw) {
    if (!p || typeof p !== "object") continue;
    const obj = p;
    if (!("payload" in obj)) continue;
    out.push({
      label: typeof obj.label === "string" ? obj.label : "mutation",
      rationale: typeof obj.rationale === "string" ? obj.rationale : "",
      payload: obj.payload
    });
    if (maxProposals !== void 0 && out.length >= maxProposals) break;
  }
  return out;
}

// src/researcher.ts
var CallbackResearcher = class {
  constructor(callbacks) {
    this.callbacks = callbacks;
  }
  callbacks;
  inspectFailures(runs) {
    return this.callbacks.inspectFailures(runs);
  }
  proposeChange(failures) {
    return this.callbacks.proposeChange(failures);
  }
  applyChange(changes, baseline) {
    return this.callbacks.applyChange(changes, baseline);
  }
  evaluateChange(plan) {
    return this.callbacks.evaluateChange(plan);
  }
};
var NoopResearcher = class {
  hint;
  constructor(hint = "NoopResearcher: no implementation wired") {
    this.hint = hint;
  }
  async inspectFailures(_runs) {
    throw new Error(`${this.hint} (inspectFailures not implemented)`);
  }
  async proposeChange(_failures) {
    throw new Error(`${this.hint} (proposeChange not implemented)`);
  }
  async applyChange(_changes, _baseline) {
    throw new Error(`${this.hint} (applyChange not implemented)`);
  }
  async evaluateChange(_plan) {
    throw new Error(`${this.hint} (evaluateChange not implemented)`);
  }
};

export {
  InMemoryFeedbackTrajectoryStore,
  FileSystemFeedbackTrajectoryStore,
  createFeedbackTrajectory,
  assignFeedbackSplit,
  withAssignedFeedbackSplit,
  feedbackTrajectoryToDatasetScenario,
  feedbackTrajectoriesToDatasetScenarios,
  feedbackTrajectoryToOptimizerRow,
  feedbackTrajectoriesToOptimizerRows,
  replayFeedbackTrajectory,
  replayFeedbackTrajectories,
  summarizePreferenceMemory,
  renderPreferenceMemoryMarkdown,
  serializeFeedbackTrajectoriesJsonl,
  parseFeedbackTrajectoriesJsonl,
  controlRunToFeedbackTrajectory,
  HeldOutGate,
  dominates,
  paretoFrontier,
  scalarScore,
  crowdingDistance,
  paretoFrontierWithCrowding,
  InMemoryTrialCache,
  runPromptEvolution,
  runMultiShotOptimization,
  defaultMultiShotObjectives,
  trialTraceFromMultiShotTrial,
  DEFAULT_MUTATION_PRIMITIVES,
  buildReflectionPrompt,
  parseReflectionResponse,
  CallbackResearcher,
  NoopResearcher
};
//# sourceMappingURL=chunk-3HYQXPC2.js.map