/**
 * memory-classify MCP tool — classifies an unstructured document into typed
 * sections via Claude Haiku, ready for memory-ingest to write as typed
 * graph nodes.
 *
 * Pairs with memory-ingest-extract (which produces the text) and memory-ingest
 * (which consumes the typed structure). The classifier output is a deterministic
 * JSON shape — every `kind` is verified against the live ontology label set
 * before reaching this tool's caller, so a hallucinated label can never reach
 * the graph writer.
 */
import { extractCache } from "./memory-ingest-extract.js";
import { classifyDocument } from "../lib/llm-classifier.js";
import { withWriteEvent } from "../lib/log-ingest.js";
/**
 * Natural-edge map pasted into the classifier prompt. Mirrors
 * schema-base.md "Section kinds" table. Every section becomes a `:Section`
 * node with the listed secondary label (e.g. `:Section:Position`).
 *
 * For identity kinds: anchorEdge points from the document subject to the
 * multi-labeled section node. For structural and contract-clause kinds:
 * anchorEdge is null — the section is anchored only via HAS_SECTION + NEXT.
 * Special-case extras for Parties + Definitions are emitted via documentEdges
 * and section-level related entries.
 */
const NATURAL_EDGE_MAP = `Section kind                     | Anchor edge (direction = from-anchor unless noted)
Position (identity)              | (anchor:UserProfile)-[:HAS_POSITION]->(:Section:Position); section -[:AT]-> related:Organization (merge:true)
Education (identity)             | (anchor:UserProfile)-[:ATTENDED {degree, startDate, endDate}]->(:Section:Education); section -[:ATTENDED]-> related:Organization {organizationCategory:'educational'} (merge:true)
Credential (identity)            | (anchor:UserProfile)-[:HOLDS]->(:Section:Credential)
Skill (identity)                 | (anchor:UserProfile)-[:HAS_SKILL]->(:Section:Skill)
Biography (identity)             | (anchor:UserProfile)-[:DESCRIBED_BY]->(:Section:Biography)
Project (standalone, not :Section) | (anchor:UserProfile)-[:CREATED]->(:Project); optional (:Project)-[:UNDER]->related:Organization (merge:true)
Preface, Abstract, Introduction, TableOfContents, Chapter, Conclusion, Appendix, Bibliography, Glossary, Acknowledgments (structural)
                                 | anchorEdge: null — anchored only via (:KnowledgeDocument)-[:HAS_SECTION]->(:Section:<Kind>) + (:Section)-[:NEXT]->(:Section)
Parties, Recitals, Definitions, Scope, Term, Payment, Confidentiality, IntellectualProperty, Warranties, Indemnification, Liability, Termination, GoverningLaw, ForceMajeure, Notices, EntireAgreement, Amendment, Assignment, Severability, Signatures (contract-clause)
                                 | anchorEdge: null — anchored via HAS_SECTION + NEXT; for Parties section, additionally emit top-level documentEdges PARTY entries; for Definitions, emit related DefinedTerm nodes with edge type DEFINES (direction outgoing from the Definitions section).
Other (label fallback)           | anchorEdge: null — section-kind closure miss; you MUST also include 'classifierReason' (one-line about-what)

Set "anchorEdge" to null for any kind whose row says "anchorEdge: null". For others, emit { "type": "<edge>", "direction": "from-anchor", "properties": { ... edge properties if any } }.`;
export async function memoryClassify(params) {
    return withWriteEvent({ tool: "memory-classify", accountId: params.accountId, name: params.attachmentId }, () => memoryClassifyImpl(params));
}
async function memoryClassifyImpl(params) {
    const { accountId, attachmentId, anchorDescription, liveSchemaSource } = params;
    const cached = extractCache.get(attachmentId);
    if (!cached) {
        throw new Error(`No cached extract found for attachment "${attachmentId}". ` +
            `Call memory-ingest-extract first.`);
    }
    // Live ∪ declared labels — the gate the validator uses for memory-write.
    // The classifier sees the same set so its output and the validator agree
    // by construction.
    const ontologyLabels = liveSchemaSource.recognisedLabels();
    return classifyDocument({
        accountId,
        anchorDescription,
        ontologyLabels,
        naturalEdgeMap: NATURAL_EDGE_MAP,
        documentText: cached.text,
    });
}
//# sourceMappingURL=memory-classify.js.map