import { type TrainingItem } from "../items.js"; import { type Corpus } from "../corpus.js"; /** A single oasst2 message node (the fields we use; the tree nests via replies). */ interface OasstNode { role?: string; text?: string; rank?: number | null; deleted?: boolean; replies?: OasstNode[]; } /** One conversational turn extracted from a tree. */ export interface OasstTurn { role: string; text: string; } /** Collapse a conversation tree to ONE linear path: at each node, descend into * its best-ranked, non-deleted reply (rank 0 preferred; unranked sorts last). * Returns the ordered turns (already strictly alternating in this corpus). */ export declare function bestOasstPath(root: OasstNode): OasstTurn[]; /** Translate ONE multi-turn oasst2 conversation into SEMA training items. * * This is the ONE stage where cumulative continuous context is truly necessary: * the data is a real multi-turn dialogue, and what must be learned is how each * turn follows from the WHOLE conversation so far — not from the previous turn * alone. The conversation is emitted ONLY as the accumulated walk; standalone * turn experiences and local adjacent-pair facts are NOT emitted (they are * subsumed by it and would merely replicate the content). * * The walk is the pattern proven in test/13-conversation.test.mjs * ("teachConversation"): each turn is the continuation of all prior turns, * with BARE turn text — NO "User:/Assistant:" labels. The SHAPE is identical * (cumulative context → next turn); the join string is not, and does not need * to be — that file joins with nothing and this corpus joins with "\n" (see * `accumulate`). Saying "byte-for-byte", as this comment used to, invites the * reading that the two must agree on a separator. They must not agree, * because there is nothing to agree about: turn boundaries are offsets, and * the join string is just corpus text. Roles already * alternate by position in an oasst2 best-path (the root is a prompter), so a * label adds nothing the position does not, while a clean continuation matches * the test's recall (predictNext queries bare prior turns) and lets a turn share * its gist with the same text elsewhere (e.g. an Aya question stored bare). * * Returns [] for a conversation below the multi-turn threshold, so callers can * simply skip empties. */ export declare function oasstConversationToItems(turns: OasstTurn[], minTurns?: number): TrainingItem[]; /** The row adapter: ONE line of the tree dump → its deposits. Returns null for * a tree with no prompt and for every single-turn tree — the latter is the * stage's design, not a defect, which is why the reader counts it `unusable` * rather than `skipped`. */ export declare function oasstTreeToItems(row: unknown): TrainingItem[] | null; export declare const oasst2: Corpus; export {};