import {
  isDirectAnswerEligible
} from "./chunk-Y4FHOFJ2.js";
import {
  throwIfAborted
} from "./chunk-PVGDJXVK.js";
import {
  normalizeRecallTokens
} from "./chunk-DT5TVLJE.js";

// src/taxonomy/resolver.ts
var DEFAULT_CATEGORY_ID = "facts";
function resolveCategory(content, memoryCategory, taxonomy) {
  const contentLower = content.toLowerCase();
  const matches = taxonomy.categories.filter(
    (cat) => cat.memoryCategories.includes(memoryCategory)
  );
  if (matches.length === 0) {
    const fallback = taxonomy.categories.find((c) => c.id === DEFAULT_CATEGORY_ID) ?? taxonomy.categories[0];
    if (!fallback) {
      return {
        categoryId: DEFAULT_CATEGORY_ID,
        confidence: 0,
        reason: "Taxonomy is empty; using default category",
        alternatives: []
      };
    }
    const alternatives2 = taxonomy.categories.filter((c) => c.id !== fallback.id).map((c) => ({
      categoryId: c.id,
      reason: c.description
    }));
    return {
      categoryId: fallback.id,
      confidence: 0.3,
      reason: `No taxonomy category maps to MemoryCategory "${memoryCategory}"; falling back to "${fallback.name}"`,
      alternatives: alternatives2
    };
  }
  if (matches.length === 1) {
    const match = matches[0];
    const alternatives2 = taxonomy.categories.filter((c) => c.id !== match.id).map((c) => ({
      categoryId: c.id,
      reason: c.description
    }));
    return {
      categoryId: match.id,
      confidence: 1,
      reason: `Unique match: MemoryCategory "${memoryCategory}" maps to "${match.name}"`,
      alternatives: alternatives2
    };
  }
  const scored = matches.map((cat) => ({
    cat,
    keywordScore: computeKeywordScore(contentLower, cat)
  }));
  scored.sort((a, b) => {
    if (b.keywordScore !== a.keywordScore) return b.keywordScore - a.keywordScore;
    return a.cat.priority - b.cat.priority;
  });
  const best = scored[0];
  const runnerUp = scored[1];
  const confidence = best.keywordScore > 0 && (!runnerUp || best.keywordScore > runnerUp.keywordScore) ? 0.9 : 0.7;
  const alternatives = taxonomy.categories.filter((c) => c.id !== best.cat.id).map((c) => ({
    categoryId: c.id,
    reason: c.description
  }));
  const reason = best.keywordScore > 0 ? `Filing rules for "${best.cat.name}" matched content keywords (priority ${best.cat.priority})` : `Priority tie-break: "${best.cat.name}" has lowest priority number (${best.cat.priority})`;
  return {
    categoryId: best.cat.id,
    confidence,
    reason,
    alternatives
  };
}
function computeKeywordScore(contentLower, cat) {
  let score = 0;
  const ruleText = [...cat.filingRules, cat.description].join(" ").toLowerCase();
  const keywords = ruleText.split(/[^a-z0-9]+/).filter((w) => w.length >= 3);
  for (const kw of keywords) {
    if (contentLower.includes(kw)) {
      score += 1;
    }
  }
  return score;
}

// src/direct-answer-wiring.ts
async function tryDirectAnswer(input) {
  const { query, namespace, config, sources, queryEntityRefs, abortSignal } = input;
  const eligibilityConfig = {
    enabled: config.recallDirectAnswerEnabled,
    tokenOverlapFloor: config.recallDirectAnswerTokenOverlapFloor,
    importanceFloor: config.recallDirectAnswerImportanceFloor,
    ambiguityMargin: config.recallDirectAnswerAmbiguityMargin,
    eligibleTaxonomyBuckets: config.recallDirectAnswerEligibleTaxonomyBuckets
  };
  if (!eligibilityConfig.enabled) {
    return isDirectAnswerEligible({
      query,
      candidates: [],
      config: eligibilityConfig,
      queryEntityRefs
    });
  }
  if (normalizeRecallTokens(query).length === 0) {
    return isDirectAnswerEligible({
      query,
      candidates: [],
      config: eligibilityConfig,
      queryEntityRefs
    });
  }
  throwIfAborted(abortSignal, "direct-answer wiring aborted");
  const memories = await sources.listCandidateMemories({ namespace, abortSignal });
  throwIfAborted(abortSignal, "direct-answer wiring aborted");
  const candidates = [];
  for (const memory of memories) {
    throwIfAborted(abortSignal, "direct-answer wiring aborted");
    const trustZone = await sources.trustZoneFor(memory.frontmatter.id);
    throwIfAborted(abortSignal, "direct-answer wiring aborted");
    if (trustZone !== "trusted") continue;
    const decision = resolveCategory(
      memory.content,
      memory.frontmatter.category,
      sources.taxonomy
    );
    const taxonomyBucket = decision.categoryId;
    if (!eligibilityConfig.eligibleTaxonomyBuckets.includes(taxonomyBucket)) continue;
    const importanceScore = sources.importanceFor(memory);
    candidates.push({
      memory,
      trustZone,
      taxonomyBucket,
      importanceScore
    });
  }
  throwIfAborted(abortSignal, "direct-answer wiring aborted");
  return isDirectAnswerEligible({
    query,
    candidates,
    config: eligibilityConfig,
    queryEntityRefs
  });
}

export {
  resolveCategory,
  tryDirectAnswer
};
//# sourceMappingURL=chunk-6AUUAZEX.js.map