import {
  objectiveEval
} from "./chunk-YEHAEDUD.js";

// src/knowledge/readiness.ts
function scoreKnowledgeReadiness(options) {
  const now = options.now ?? /* @__PURE__ */ new Date();
  const requirements = options.requirements.map(normalizeRequirement);
  const missing = requirements.filter((requirement) => isRequirementMissing(requirement, now));
  const blockingMissingRequirements = missing.filter(isBlockingGap);
  const nonBlockingGaps = missing.filter((requirement) => !isBlockingGap(requirement));
  const readinessScore = weightedReadinessAt(requirements, now);
  const bundle = {
    taskId: options.taskId,
    requirements,
    evidenceIds: unique([
      ...options.evidenceIds ?? [],
      ...requirements.flatMap((r) => r.evidenceIds)
    ]),
    claimIds: unique(options.claimIds ?? []),
    wikiPageIds: unique(options.wikiPageIds ?? []),
    userAnswers: options.userAnswers ?? {},
    missing,
    readinessScore,
    metadata: options.metadata
  };
  const recommendedAction = chooseRecommendedAction(blockingMissingRequirements, nonBlockingGaps);
  const severity = blockingMissingRequirements.length > 0 ? "critical" : nonBlockingGaps.some((gap) => gap.importance === "high") ? "warning" : "info";
  const reason = blockingMissingRequirements.length > 0 ? `${blockingMissingRequirements.length} blocking knowledge requirement(s) are missing.` : nonBlockingGaps.length > 0 ? `${nonBlockingGaps.length} non-blocking knowledge gap(s) remain.` : "All declared knowledge requirements are ready.";
  return {
    taskId: options.taskId,
    readinessScore,
    blockingMissingRequirements,
    nonBlockingGaps,
    recommendedAction,
    bundle,
    severity,
    reason
  };
}
function blockingKnowledgeEval(report, options = {}) {
  const minimumScore = options.minimumScore ?? 0.7;
  const passed = report.blockingMissingRequirements.length === 0 && report.readinessScore >= minimumScore;
  if (options.emitter) {
    void options.emitter.emit({
      kind: "custom",
      payload: knowledgeReadinessTracePayload(report, { passed, minimumScore })
    }).catch(() => void 0);
  }
  return objectiveEval({
    id: options.id ?? "knowledge-ready",
    passed,
    score: report.readinessScore,
    severity: passed ? "info" : report.severity,
    detail: report.reason,
    evidence: report.blockingMissingRequirements.map((r) => r.id).join(", ") || void 0,
    metadata: { knowledgeReadiness: report }
  });
}
function knowledgeReadinessTracePayload(report, options = {}) {
  return {
    kind: "readiness_scored",
    taskId: report.taskId,
    passed: options.passed ?? report.blockingMissingRequirements.length === 0,
    readinessScore: report.readinessScore,
    minimumScore: options.minimumScore,
    blockingRequirementIds: report.blockingMissingRequirements.map((r) => r.id),
    nonBlockingRequirementIds: report.nonBlockingGaps.map((r) => r.id),
    recommendedAction: report.recommendedAction,
    severity: report.severity,
    reason: report.reason
  };
}
function userQuestionsForKnowledgeGaps(gaps) {
  return gaps.filter((gap) => gap.acquisitionMode === "ask_user" || gap.fallbackPolicy === "ask").map((gap) => ({
    id: `question_${gap.id}`,
    question: `Please provide: ${gap.description}`,
    reason: `Required for ${gap.requiredFor.join(", ") || "the task"}.`,
    requirementId: gap.id,
    importance: gap.importance,
    answerType: gap.sensitivity === "secret" ? "credential" : "free_text",
    impactIfUnknown: impactFor(gap)
  }));
}
function acquisitionPlansForKnowledgeGaps(gaps) {
  const byMode = /* @__PURE__ */ new Map();
  for (const gap of gaps) {
    const mode = planMode(gap.acquisitionMode);
    if (!mode) continue;
    const bucket = byMode.get(mode) ?? [];
    bucket.push(gap);
    byMode.set(mode, bucket);
  }
  return [...byMode.entries()].map(([mode, requirements]) => ({
    id: `acquire_${mode}`,
    requirementIds: requirements.map((r) => r.id),
    mode,
    description: descriptionForPlan(mode, requirements),
    priority: maxImportance(requirements.map((r) => r.importance)),
    questions: mode === "ask_user" ? userQuestionsForKnowledgeGaps(requirements) : void 0
  }));
}
function normalizeRequirement(requirement) {
  return {
    ...requirement,
    confidenceNeeded: clamp01(requirement.confidenceNeeded),
    currentConfidence: clamp01(requirement.currentConfidence),
    evidenceIds: unique(requirement.evidenceIds)
  };
}
function weightedReadinessAt(requirements, now) {
  if (requirements.length === 0) return 1;
  let weightSum = 0;
  let scoreSum = 0;
  for (const requirement of requirements) {
    const weight = importanceWeight(requirement.importance);
    const score = isExpired(requirement, now) ? 0 : requirement.confidenceNeeded <= 0 ? 1 : Math.min(1, requirement.currentConfidence / requirement.confidenceNeeded);
    weightSum += weight;
    scoreSum += weight * score;
  }
  return clamp01(scoreSum / weightSum);
}
function isRequirementMissing(requirement, now) {
  return isExpired(requirement, now) || requirement.currentConfidence < requirement.confidenceNeeded;
}
function isExpired(requirement, now) {
  if (!requirement.validUntil) return false;
  const deadline = Date.parse(requirement.validUntil);
  if (!Number.isFinite(deadline)) return true;
  return deadline <= now.getTime();
}
function isBlockingGap(requirement) {
  return requirement.importance === "blocking" || requirement.fallbackPolicy === "block" || requirement.sensitivity === "secret";
}
function chooseRecommendedAction(blocking, nonBlocking) {
  const gaps = blocking.length > 0 ? blocking : nonBlocking;
  if (gaps.length === 0) return "run_agent";
  if (gaps.some((gap) => gap.acquisitionMode === "ask_user" || gap.fallbackPolicy === "ask"))
    return "ask_user";
  if (gaps.some((gap) => gap.acquisitionMode === "query_connector")) return "query_connectors";
  if (gaps.some(
    (gap) => gap.acquisitionMode === "inspect_repo" || gap.acquisitionMode === "run_command"
  ))
    return "inspect_repo";
  if (gaps.some((gap) => gap.acquisitionMode === "search_web")) return "collect_web_data";
  if (gaps.some((gap) => gap.acquisitionMode === "not_available")) return "abort_or_rescope";
  if (nonBlocking.some((gap) => gap.importance === "high")) return "build_domain_wiki";
  return "continue_with_caveat";
}
function planMode(mode) {
  if (mode === "infer_low_confidence" || mode === "not_available") return null;
  return mode;
}
function descriptionForPlan(mode, requirements) {
  const labels = requirements.map((r) => r.description).join("; ");
  if (mode === "ask_user") return `Ask the user for: ${labels}`;
  if (mode === "search_web") return `Search web or documentation sources for: ${labels}`;
  if (mode === "query_connector") return `Query configured connectors for: ${labels}`;
  if (mode === "inspect_repo") return `Inspect repository context for: ${labels}`;
  if (mode === "run_command") return `Run local commands to collect: ${labels}`;
  return `Build domain wiki evidence for: ${labels}`;
}
function impactFor(requirement) {
  if (requirement.fallbackPolicy === "block") return "The agent should not run until this is known.";
  if (requirement.fallbackPolicy === "continue_with_caveat")
    return "The agent may continue, but must disclose uncertainty.";
  if (requirement.fallbackPolicy === "use_default")
    return "The agent will use the configured default if skipped.";
  return "The agent should ask before continuing.";
}
function maxImportance(values) {
  const order = ["blocking", "high", "medium", "low"];
  return order.find((value) => values.includes(value)) ?? "low";
}
function importanceWeight(importance) {
  if (importance === "blocking") return 8;
  if (importance === "high") return 4;
  if (importance === "medium") return 2;
  return 1;
}
function clamp01(value) {
  if (!Number.isFinite(value)) return 0;
  return Math.max(0, Math.min(1, value));
}
function unique(items) {
  return [...new Set(items)];
}

export {
  scoreKnowledgeReadiness,
  blockingKnowledgeEval,
  knowledgeReadinessTracePayload,
  userQuestionsForKnowledgeGaps,
  acquisitionPlansForKnowledgeGaps
};
//# sourceMappingURL=chunk-Q2JRAWRI.js.map