@athenox/talos
Version:
Talos: a backend you describe instead of write. Declare a schema, write the rules in plain language, map URLs to sentences; a small built-in model turns them into query plans.
62 lines (61 loc) • 2.2 kB
TypeScript
/**
* Ranking rows for one reader: what they read, what readers like them read,
* what is popular and recent — over rows a sentence route already chose.
*
* The route's plan picks the candidates ("recommande des articles publies"); this
* orders them. Four signals, each in [0, 1], mixed by `weights`:
*
* - content: TF-IDF cosine between each candidate's text and the texts of what
* the reader interacted with (their profile);
* - together: how often the candidate was read by the readers who read the
* reader's items ("readers of X also read Y");
* - popular: the candidate's own interaction count;
* - recent: a half-life decay on a date column.
*
* Items the reader already interacted with are left out. A reader with no
* history gets popular and recent rows. Everything is computed per request
* over the candidates, which suits hundreds to a few thousand rows.
*/
export type RecommendOptions = {
/** the reader, or null for a visitor */
user: unknown;
/** the interactions: one row per (user, item), e.g. article views */
interactions?: {
table: string;
user: string;
item: string;
};
/** physical text columns of the candidate rows */
text?: string[];
/** physical date column for recency, and its half-life in days */
date?: string;
halfLife?: number;
weights?: {
content?: number;
together?: number;
popular?: number;
recent?: number;
};
limit?: number;
/** keep the rows the reader already interacted with (default: leave them out) */
keepSeen?: boolean;
};
type Store = {
all(sql: string, ...p: unknown[]): any;
};
/**
* Rows ordered by how close their text is to a row or a text: "à lire aussi",
* near-duplicates. Uses the embedder, and word overlap when it is absent.
*/
export declare function similar(rows: Record<string, any>[], o: {
to: string;
text: string[];
exclude?: unknown;
limit?: number;
min?: number;
}): {
score: number;
}[];
type Row = Record<string, any>;
export declare function rank(rows: Row[], o: RecommendOptions, store: Store, q: (s: string) => string): Promise<Row[]>;
export {};