/** * ThinkingBlockManager — thinking-block lifecycle across model switches. * * Frontier models with always-on adaptive thinking return `thinking` blocks * whose `signature` ties them to the producing model. Two rules follow: * * - **Same model, multi-turn:** pass thinking blocks back *unchanged* (the * signature is validated server-side). * - **Switching models (e.g. a refusal fallback):** *strip* `thinking` and * `redacted_thinking` blocks from prior turns — another model ignores them * but still bills them as input tokens. * * It also guards prompts against the `reasoning_extraction` refusal: asking a * model to reproduce its internal reasoning as response text can be declined. * * Satisfies the `ThinkingSink` contract consumed by * {@link ../lib/model-gateway!GovernedModelGateway}, which calls * {@link ThinkingBlockManager.stripForModelSwitch} on a cross-model retry — but * only when it is *not* redeeming a fallback credit (credit redemption requires * an exact body match, so blocks stay). * * @module ThinkingBlockManager * @version 1.0.0 * @license MIT */ import type { ModelMessage } from './model-gateway'; /** Result of {@link ThinkingBlockManager.guardAgainstReasoningExtraction}. */ export interface ReasoningExtractionCheck { /** Whether any reasoning-extraction phrasing was detected. */ flagged: boolean; /** The matched substrings, for surfacing to the caller. */ matches: string[]; } /** * Manages thinking blocks across same-model turns and cross-model fallbacks. * * @example * ```typescript * const thinking = new ThinkingBlockManager(); * const gateway = new GovernedModelGateway({ caller, primaryModel, fallbackModels, thinking }); * * // Guard a system prompt before sending it to a refusal-prone model: * const check = thinking.guardAgainstReasoningExtraction(systemPrompt); * if (check.flagged) console.warn('reasoning-extraction risk:', check.matches); * ``` */ export declare class ThinkingBlockManager { /** * Strip model-bound thinking blocks from prior assistant turns before a * cross-model retry. `fallback`, `text`, and tool blocks are preserved; only * `thinking` / `redacted_thinking` blocks are removed. Messages whose content * is not a block array are returned untouched. * * @param messages The conversation to clean. * @returns A new array with model-bound blocks removed. */ stripForModelSwitch(messages: ModelMessage[]): ModelMessage[]; /** * Identity transform documenting the same-model rule: thinking blocks must be * passed back **unchanged** when continuing on the same model. * * @param messages The conversation. * @returns The same messages, unchanged. */ preserveForSameModel(messages: ModelMessage[]): ModelMessage[]; /** Whether any message carries a model-bound thinking block. */ hasThinkingBlocks(messages: ModelMessage[]): boolean; /** * Detect prompt text that asks a model to reproduce its internal reasoning as * response text — which can trigger a `reasoning_extraction` refusal. Read the * structured `thinking` blocks instead of prompting for reasoning in the body. * * @param text The prompt or instruction to inspect. */ guardAgainstReasoningExtraction(text: string): ReasoningExtractionCheck; } //# sourceMappingURL=thinking-blocks.d.ts.map