/** * The text core the language-facing intelligence tools compute with. * * Companion to analytics-core.ts, and it exists for the same reason: the six * tools being implemented published 48 operations and computed nothing, so * every string they now return has to come from the caller's own text by a * named method. Summarisation here is EXTRACTIVE -- it selects sentences the * caller wrote and never generates prose -- because this package has no * language model and inventing a sentence would be the same defect in a new * costume. * * Line-level change detection is not reimplemented here: generateDiff and * calculateSimilarity in ../shared/diff-utils.js already do it, and the * tools call those. */ /** Is this token a stop word? Exposed so a caller can see the rule. */ export declare const isStopWord: (token: string) => boolean; /** How many stop words the list holds, so a test can pin the rule's size. */ export declare const STOP_WORD_COUNT: number; /** * Word tokens, lowercased, stop words and single characters dropped. * Underscores and hyphens are kept inside a token, because the text these * tools are given is full of `cache_hit` and `smart-read` and splitting * those destroys the term. */ export declare const tokenize: (text: string) => string[]; /** * Sentences, by terminator followed by whitespace, with newline-separated * lines treated as boundaries too -- log lines and bullet lists carry no * full stops, and treating a whole log as one sentence makes every * summarisation result the input. */ export declare const splitSentences: (text: string) => string[]; /** Term counts for one document. */ export declare const termFrequencies: (tokens: readonly string[]) => Map; /** * Inverse document frequency, smoothed as ln(1 + N/df) so that a term * appearing in every document gets a small positive weight rather than * exactly zero -- with a single document, the unsmoothed form zeroes every * term and keyword extraction returns nothing. */ export declare const inverseDocumentFrequency: (documents: ReadonlyArray) => Map; /** One scored term. */ export interface ScoredTerm { term: string; score: number; /** Raw count in the document the score was computed for. */ count: number; } /** * The highest tf-idf terms of one document against a corpus. When the corpus * is just that document, the smoothed idf above makes this a frequency * ranking, which is the honest answer: one document carries no information * about what is distinctive. */ export declare const keyTerms: (document: readonly string[], corpus: ReadonlyArray, limit: number) => ScoredTerm[]; /** Jaccard index: shared terms over total distinct terms. */ export declare const jaccard: (a: readonly string[], b: readonly string[]) => number; /** TextRank's damping factor, as published in Mihalcea & Tarau (2004). */ export declare const TEXTRANK_DAMPING = 0.85; /** Iteration ceiling and convergence threshold for the power iteration. */ export declare const TEXTRANK_MAX_ITERATIONS = 100; export declare const TEXTRANK_TOLERANCE = 0.000001; /** * TextRank over a weighted undirected similarity graph, by power iteration. * Returns one score per node, summing to the node count, in input order. * * A node with no similar neighbour keeps the uniform score rather than * decaying to zero, so an unrelated sentence can still be selected when * nothing else is available -- which is what should happen to a one-sentence * input. */ export declare const textRank: (similarity: ReadonlyArray) => number[]; /** One sentence selected for a summary. */ export interface SelectedSentence { /** Index in the original sentence order. */ index: number; sentence: string; score: number; } /** * Extractive summary: the highest-TextRank sentences, returned IN ORIGINAL * ORDER so the result reads as the caller's own text rather than as a ranked * list. Nothing is generated or paraphrased. */ export declare const summarize: (text: string, sentenceCount: number) => SelectedSentence[]; /** A category and the terms that evidence it. */ export interface Category { name: string; /** Lowercased terms; a match is on a whole token, never a substring. */ terms: readonly string[]; } /** How strongly a document matched one category. */ export interface CategoryScore { name: string; /** Matching tokens divided by the document's token count. */ score: number; /** The category terms actually found, with their counts. */ matched: Array<{ term: string; count: number; }>; } /** * Score a document against caller-supplied categories by whole-token match. * Substring matching is deliberately not used: it makes `error` match * `terrorise` and produces a category assignment nobody can account for. * * Categories are the CALLER's, because a fixed internal taxonomy would be a * guess about their domain -- the same guess the stub tools were making when * they answered every classification with success. */ export declare const categorize: (text: string, categories: readonly Category[]) => CategoryScore[]; /** * Terms whose share of the text rose or fell between two periods, by * difference in relative frequency. Relative and not absolute, because two * periods are rarely the same size and an absolute count would report the * longer one as the whole story. */ export interface TermShift { term: string; beforeShare: number; afterShare: number; /** afterShare - beforeShare; positive means it grew. */ delta: number; } export declare const compareTermShares: (before: string, after: string, limit: number) => TermShift[]; //# sourceMappingURL=text-core.d.ts.map