import type { TokenCounter } from './types.js'; /** * Moving stable instructions in front of the first placeholder. * * This is the largest saving Trazum knows about and the only one it used to * report without acting on. Prompt caching is a byte-for-byte prefix match, so * everything after the first `{{placeholder}}` is re-read at full price on every * call. Measured on a 1,178-token support prompt: 14 tokens cacheable as written, * 1,174 after rearranging the *same content* — $227.65 a month at 50,000 calls. * * No rule can compete with that, because a rule deletes a few percent of tokens * while this changes the price of 98% of them. * * **It is also the most dangerous thing in this repository**, which is why it is * not a rule and not part of `aggressive`. Every other transformation removes * text whose absence is local. This one moves text, and order carries meaning: * "Summarise the text above" is correct where it sits and nonsense in front of * the text it points at. So the whole design here is about what to *refuse*. * * Three refusals, in order of how much they cost: * * 1. **A block containing a backward reference stays put** — and so does * everything after it. Moving a later block past a pinned one changes their * order relative to each other, which is the same class of harm. * 2. **Only whole blocks move.** Blocks are separated by blank lines, so a * sentence is never severed from the paragraph that qualifies it. * 3. **Nothing moves if the prompt has no placeholder**, or if the resulting * prefix would not clear the model's cacheable minimum anyway — a * rearrangement that buys nothing is a diff for its own sake. */ export interface ReorderedBlock { text: string; tokens: number; } export interface DeclinedBlock { text: string; /** * Why it stayed. `backward-reference` names the phrase found; `after-pinned` * means an earlier block was pinned and moving this one would reorder the two. */ reason: 'backward-reference' | 'after-pinned' | 'uncovered-script'; /** The phrase that pinned it, for `backward-reference`. */ phrase?: string; /** The script with no phrase list, for `uncovered-script`. */ script?: string; } export interface ReorderResult { /** The rearranged prompt, or the original when nothing could move. */ text: string; /** Blocks moved ahead of the first placeholder, in their original order. */ moved: ReorderedBlock[]; /** Blocks left where they were, with the reason. */ declined: DeclinedBlock[]; /** Tokens that moved from unpriced-every-call into the cacheable prefix. */ tokensMoved: number; /** Cacheable prefix before and after, so the gain is visible rather than claimed. */ prefixTokensBefore: number; prefixTokensAfter: number; } export interface ReorderOptions { count?: TokenCounter; /** * Do not rearrange unless the prefix ends up at least this long. Defaults to * 0 — the caller knows the model's cacheable minimum and this module does not. * * The bar is on the **resulting prefix**, not on the amount moved. Those are * different questions, and asking the second one refuses a real saving: a * prompt whose head already clears the minimum gains from any block that joins * it, however small. Asking "did 200 tokens move?" answers "no" and reports * that nothing could move, which is not what happened. */ minPrefixTokens?: number; } /** * Rearranges a prompt so its stable instructions sit in the cacheable prefix. * * Returns the original text unchanged when nothing can safely move, and always * reports what it declined and why — a saving Trazum silently chose not to take * is one the author cannot evaluate. */ export declare function reorderForCache(prompt: string, options?: ReorderOptions): ReorderResult; //# sourceMappingURL=reorder.d.ts.map