import type { AssistantMessage, Model } from "@gajae-code/ai/core"; import { type ModelSelectorValue } from "../config/model-selector-value"; /** * Normalize a model selector for display: strip ANSI escape sequences and * control characters, remove Unicode format characters, replace tabs with * spaces, and bound the width. One shared implementation so the TUI render and * the print-mode stderr render interpolate the identical safe value (#4653 * review: centralize selector sanitization instead of leaving each surface to * bound itself). */ export declare function sanitizeModelSelectorForDisplay(selector: string): string; /** * Session capabilities the hint resolver reads. Everything is optional so * lightweight host/test contexts without model plumbing degrade to the static * guidance instead of throwing. */ export interface ProviderSafetyStopHintSession { getConfiguredModelChainState?(role: string): { entries: readonly string[]; origin: string; identity?: string; explicitHead: boolean; } | undefined; settings?: { getModelRole?(role: string): ModelSelectorValue | undefined; }; getAvailableModels?(): Model[]; } /** Whether an assistant message terminated as a provider safety stop (typed or legacy-persisted). */ export declare function isProviderSafetyStop(message: AssistantMessage): boolean; /** * The `provider/id` identity of the model that produced an assistant message. * The message's own `provider`/`model` fields are the authoritative identity of * the refusing attempt (they survive model switches after the error). */ export declare function refusingModelSelector(message: AssistantMessage): string | undefined; /** * Resolve a safe, valid alternate model selector from the default role's * configured chain — one that is NOT the model that refused. Presentation-only: * reads configured intent, dispatches nothing, and mutates nothing (#4650). * * An entry is named only when the authoritative model selector resolver accepts * it (`resolveSelector` with `allowInvalidThinkingSelectorFallback: false`, so * malformed suffixes like `:bogus` fail closed while route-suffixed IDs keep * their exact-ID semantics) AND the concrete model it resolves to differs from * the refuser. * * The returned selector is RECONSTRUCTED from the resolved model — always * `provider/id` qualified, never the original entry (#4653 review: the hint * resolver runs without usage-preference context, so a bare/fuzzy/glob entry * that resolves here can paste-resolve differently under the real `/model` * command's usage-preference context; a provider-qualified selector pins the * advertised command to exactly the model that was validated). Only a thinking * suffix that itself validated is carried over, so the suggested command is one * the resolver parses with identical semantics. */ export declare function resolveSafetyStopAlternateSelector(refuserSelector: string | undefined, chain: ModelSelectorValue | readonly string[] | undefined, availableModels: readonly Model[]): string | undefined; /** * Bounded guidance shown after a provider safety stop: the failure is * model-specific, the context need not be discarded, and the session continues * after a manual switch. The configured alternate and the canonical manual * switch command are named only when a validated alternate was resolved; the * hint never claims the alternate is guaranteed to accept the same context. */ export declare function formatProviderSafetyStopHint(alternateSelector: string | undefined): string; /** * Resolve the hint to display for a terminal provider safety stop, against the * session's current configured default chain and available catalog. Returns a * hint string for safety stops (static guidance when no valid alternate can be * named) and `undefined` for every other error kind, so unrelated errors keep * their existing rendering untouched. */ export declare function resolveProviderSafetyStopHint(message: AssistantMessage, session: ProviderSafetyStopHintSession | undefined): string | undefined; /** * Compose the display error line for a provider safety stop: the provider's own * refusal text is always retained verbatim, with the hint appended on a new * line. Returns `undefined` for non-safety-stop errors. */ export declare function formatProviderSafetyStopDisplayError(message: AssistantMessage, alternateSelector: string | undefined): string | undefined;