import {
  CaptureIntegrityError
} from "./chunk-ONWEPEDO.js";

// src/trace/integrity.ts
var RunIntegrityError = class extends CaptureIntegrityError {
  constructor(report) {
    super(
      `Run ${report.runId} failed integrity check: ${report.issues.map((i) => i.code).join(", ")}`
    );
    this.report = report;
  }
  report;
};
async function assertRunCaptured(store, runId, expectations = {}) {
  const issues = [];
  const run = await store.getRun(runId);
  if (!run) {
    return {
      ok: false,
      runId,
      llmSpanCount: 0,
      judgeSpanCount: 0,
      toolSpanCount: 0,
      rawProviderEventCount: 0,
      rawSpanCoverage: { covered: 0, total: 0 },
      issues: [{ code: "no_run", message: `Run ${runId} not found in store.` }]
    };
  }
  const spans = await store.spans({ runId });
  const llmSpans = spans.filter((s) => s.kind === "llm");
  const judgeSpans = spans.filter((s) => s.kind === "judge");
  const toolSpans = spans.filter((s) => s.kind === "tool");
  const llmMin = expectations.llmSpansMin ?? 0;
  const judgeMin = expectations.judgeSpansMin ?? 0;
  const toolMin = expectations.toolSpansMin ?? 0;
  if (llmSpans.length < llmMin) {
    issues.push({
      code: "missing_llm_spans",
      message: `Expected \u2265 ${llmMin} LLM spans, found ${llmSpans.length}.`,
      detail: { expected: llmMin, found: llmSpans.length }
    });
  }
  if (judgeSpans.length < judgeMin) {
    issues.push({
      code: "missing_judge_spans",
      message: `Expected \u2265 ${judgeMin} judge spans, found ${judgeSpans.length}.`,
      detail: { expected: judgeMin, found: judgeSpans.length }
    });
  }
  if (toolSpans.length < toolMin) {
    issues.push({
      code: "missing_tool_spans",
      message: `Expected \u2265 ${toolMin} tool spans, found ${toolSpans.length}.`,
      detail: { expected: toolMin, found: toolSpans.length }
    });
  }
  let rawEventCount = 0;
  let coverage = { covered: 0, total: llmSpans.length };
  if (expectations.rawSink) {
    if (!expectations.rawSink.list) {
      issues.push({
        code: "no_raw_sink",
        message: "Provided rawSink does not implement list(); cannot verify capture."
      });
    } else {
      const events = await expectations.rawSink.list({ runId });
      rawEventCount = events.length;
      const rawMin = expectations.rawProviderEventsMin ?? 1;
      if (rawEventCount < rawMin) {
        issues.push({
          code: "missing_raw_events",
          message: `Expected \u2265 ${rawMin} raw provider events, found ${rawEventCount}.`,
          detail: { expected: rawMin, found: rawEventCount }
        });
      }
      if (expectations.requireRawCoverageOfLlmSpans) {
        const requestEventsBySpan = new Set(
          events.filter((e) => e.direction === "request" && e.spanId).map((e) => e.spanId)
        );
        const orphaned = llmSpans.filter((s) => !requestEventsBySpan.has(s.spanId));
        coverage = { covered: llmSpans.length - orphaned.length, total: llmSpans.length };
        if (orphaned.length > 0) {
          issues.push({
            code: "orphan_llm_span",
            message: `${orphaned.length} LLM span(s) have no matching raw provider request event.`,
            detail: { orphanedSpanIds: orphaned.map((s) => s.spanId) }
          });
        }
      }
    }
  } else if (expectations.requireRawCoverageOfLlmSpans || expectations.rawProviderEventsMin) {
    issues.push({
      code: "no_raw_sink",
      message: "Raw coverage required but no rawSink supplied to the integrity check."
    });
  }
  if (expectations.requireOutcome && (run.outcome === void 0 || run.outcome === null)) {
    issues.push({
      code: "missing_outcome",
      message: `Run ${runId} has no outcome recorded.`
    });
  }
  return {
    ok: issues.length === 0,
    runId,
    llmSpanCount: llmSpans.length,
    judgeSpanCount: judgeSpans.length,
    toolSpanCount: toolSpans.length,
    rawProviderEventCount: rawEventCount,
    rawSpanCoverage: coverage,
    issues
  };
}
function throwIfRunIncomplete(report) {
  if (!report.ok) throw new RunIntegrityError(report);
}

export {
  RunIntegrityError,
  assertRunCaptured,
  throwIfRunIncomplete
};
//# sourceMappingURL=chunk-TT4KNT67.js.map