import type { ThinkingLevel } from "../internal/harness-types.js";
/**
 * Unified reasoning-intensity abstraction (design/96 S3).
 *
 * The intensity a caller requests IS a {@link ThinkingLevel} — we reuse the existing 7-tier vendor scale
 * (`off | minimal | low | medium | high | xhigh | max`) rather than forking a parallel "fast/standard/deep"
 * enum, so there is ONE knob, not two that must be kept in sync. This module is the single place that maps a
 * requested intensity to what a given endpoint can ACTUALLY honor, and reports the EFFECTIVE intensity — so a
 * request that can't be honored as asked ("high" on a binary enable-only provider like qwen/zai, or
 * "xhigh"/"max" on an endpoint whose `reasoning_effort` only accepts up to "high") is observable rather than
 * silently swallowed or 422'd (design/96 §E honesty red-line; design/46 anti-drift).
 *
 * The brain (openai.ts / anthropic.ts) consumes this. Surfacing the effective intensity to a task result is a
 * later config-domain slice (design/96 S6); here it is a pure, tested mapping.
 */
export type ReasoningIntensity = ThinkingLevel;
/** Type guard: is `v` one of the 7 {@link ThinkingLevel} tiers? (A legacy/unknown reasoning string is not.) */
export declare function isThinkingLevel(v: unknown): v is ThinkingLevel;
/**
 * THE thinking-request ENTRY predicate — does this request enter an applier's emission path at all?
 * One conjunction, three arms: the model declares reasoning (TRUTHINESS — the adapters' own
 * judgment, see the r5 note in {@link resolveReasoning}), the requested value is a real
 * {@link ThinkingLevel} (an out-of-contract value — a typo'd tier, a caller's own enum — reads as
 * ABSENCE, never as a declared tier), and it is not the explicit `"off"`.
 *
 * ENTRY gate, deliberately NOT an emitted-a-key guarantee: past this gate the per-FORMAT arms still
 * decide what (if anything) lands on the wire — `supportsReasoningEffort:false` on a format whose
 * only carrier is the effort key, a `null` levelmap entry, the binary enable keys. Those arms have
 * their own reporting shape (the `graded:false` intent-echo family, each pinned with its rationale
 * where it lives); this predicate only closes the gate the three appliers used to re-spell.
 *
 * Single-sourced here because every wire applier (openai.ts `applyThinking`, anthropic.ts's thinking
 * + effort arms, open-responses.ts `resolveWireEffort`) would otherwise re-spell the same three
 * conjuncts while the REPORTING resolver ({@link resolveReasoning}) mirrored one of them, so a
 * garbage tier puts ZERO parameters on the wire while the resolution claims a clamped-to-minimal
 * gradient. A predicate the appliers and the reporter both call cannot drift.
 */
export declare function reasoningRequestCarried(model: {
    reasoning?: boolean;
}, reasoning: unknown): reasoning is ThinkingLevel;
/** Ordinal rank of a level (`off`=0 … `max`=6). */
export declare function rankOf(level: ThinkingLevel): number;
/**
 * The `reasoning_effort` tiers an OpenAI-family endpoint accepts by DEFAULT. Conservative on purpose: a value
 * the endpoint rejects 422s the whole request, so we ship the set stock OpenAI takes
 * (`minimal | low | medium | high`) and clamp anything higher ("xhigh"/"max") down to "high". An endpoint that
 * genuinely accepts a higher tier declares it via `compat.reasoningEffortLevels`.
 */
export declare const DEFAULT_EFFORT_LEVELS: readonly ThinkingLevel[];
/**
 * The per-provider thinking wire format (mirrors `compat.thinkingFormat`). `"budget"` is the synthetic tag for
 * Anthropic's extended-thinking budget path (no `thinkingFormat` — the anthropic brain doesn't read one), kept
 * here so {@link resolveReasoning} can report ONE endpoint discriminant across both brain families.
 */
export type ReasoningFormat = "openai" | "openrouter" | "deepseek" | "together" | "zai" | "qwen" | "qwen-chat-template" | "budget"
/** Anthropic `output_config.effort` (CC 2.1.198 / Fable-5 class, design/119): the tier is a named
 *  effort string, clamped to `compat.effortLevels` — the anthropic-side twin of the OpenAI
 *  `reasoning_effort` path (thinking FORM is `thinkingMode`; effort carries the intensity). */
 | "effort"
/** OpenAI Responses API (`openai-responses` / `azure-openai-responses`, design/163): the tier rides
 *  the NESTED `reasoning: { effort }` request field (open-responses.ts `resolveWireEffort`), clamped
 *  by the same {@link resolveEffort} against `compat.reasoningEffortLevels` — NOT the completions
 *  top-level `reasoning_effort` the `"openai"` tag names. #325 review r3: before this member the
 *  resolver fell through to the completions default and labeled Responses resolutions `"openai"`. */
 | "responses";
/**
 * The Open Responses API family — every `Api` value `createOpenResponsesBrain` serves (design/163).
 * The SINGLE family discriminant: request-params.ts (reserved-key set selection) and
 * {@link resolveReasoning} (format dispatch, #325 review r4) both key off THIS set, so a new
 * Responses api value added here reaches every family-scoped behavior instead of one of two twins.
 */
export declare const RESPONSES_APIS: ReadonlySet<string>;
/** How a requested intensity resolved against one endpoint's real capability. */
export interface ReasoningResolution {
    /** The level the caller asked for. */
    requested: ThinkingLevel;
    /** The level actually in effect after mapping to what the endpoint accepts. */
    effective: ThinkingLevel;
    /**
     * True when the endpoint varies behavior by intensity (effort tiers / token budget). False = binary
     * enable-only (qwen / zai / qwen-chat-template, an effort endpoint that declares
     * `supportsReasoningEffort:false`, or a tier `Model.thinkingLevelMap` maps to `null` — the wire then
     * carries NO effort value for it): thinking is on or off and the tier is NOT honored — read this
     * alongside {@link effective}, which then echoes the request as intent only.
     */
    graded: boolean;
    /** True when {@link effective} differs from {@link requested} (the request couldn't be honored exactly). */
    clamped: boolean;
}
/** Anthropic's hard floor for an extended-thinking budget. Lives HERE (not the anthropic brain) so
 *  the cap-wins predicate below and the brain's budget-window math read ONE constant. */
export declare const MIN_THINKING_TOKENS = 1024;
/**
 * The anthropic BUDGET path's cap-wins arm (#346, single-sourced; design/119 #2 review):
 * a HARD per-request output cap (an engine-imposed override or the caller's explicit
 * `options.maxTokens` — the two lanes the brain refuses to raise) too small to host a legal thinking
 * budget (≥ {@link MIN_THINKING_TOKENS}) plus answer room means the CAP WINS and thinking is skipped
 * for the request. Shared by the wire arm (anthropic.ts, which acts on it) and
 * {@link resolveReasoning}'s budget arm (which mirrors it when the caller supplies the request
 * facts), so the skip decision and its report are one predicate — the reporter's budget arm used to
 * claim an unconditional `graded:true` gradient while this arm deleted the thinking block from the
 * very request it described. A soft (model/config-sourced) cap never skips: the brain raises it to
 * host the budget instead (`hardCap === false`).
 */
export declare function budgetCapSkipsThinking(outputCapTokens: number, hardCap: boolean): boolean;
/** The model slice the off-capability reads: the API family, the reasoning bit, the compat declaration and the levelmap. */
export interface OffCapabilityModel {
    api?: string;
    reasoning?: boolean;
    compat?: unknown;
    thinkingLevelMap?: Readonly<Partial<Record<ThinkingLevel, string | null>>>;
}
/**
 * The DEPLOYMENT-declared spelling of the explicit "off" tier on an effort-only wire (stock openai
 * completions, the Responses lane): `thinkingLevelMap.off` as a non-empty string (a provider's own
 * "none" tier), on an endpoint that takes an effort value at all (`supportsReasoningEffort` not
 * false) — else `undefined`: there is nothing to send. The effort formats have no disable key, and an
 * effort VALUE is never off (it enables reasoning at that tier), so off on those wires is spelled only
 * when the deployment says how. The two appliers and {@link thinkingOffSpelled} read this ONE
 * function, so what the wire carries and what the capability table claims cannot disagree.
 */
export declare function declaredOffSpelling(model: OffCapabilityModel): string | undefined;
/**
 * Whether the wire will CARRY a disable key for this model — off is SPELLED, never assumed. Per wire: the
 * anthropic budget form spells `{type:"disabled"}` (the ADAPTIVE form rejects it — those models think on
 * every request); deepseek `{type:"disabled"}`, the binary enable keys at `false`, openrouter/together
 * `reasoning:{enabled:false}` all spell it; the effort-only wires (stock openai completions, the Responses
 * lane) spell it only through a deployment-declared off spelling ({@link declaredOffSpelling}).
 *
 * A model whose `reasoning` is FALSY spells NOTHING: every applier returns before writing any key for it, so
 * the request is the gateway's own default — and a default-on gateway thinks regardless (three of four live
 * endpoints, 2026-09-15). This arm used to answer `true` ("a non-reasoning model never thinks"): the engine
 * may size a request by what it SENT, never by what it hopes a gateway does when told nothing. What this
 * table cannot see is a gateway that IGNORES the key it was sent — the classifier's re-ask on a no-verdict
 * reply is the seat that learns that from the reply.
 */
export declare function thinkingOffSpelled(model: OffCapabilityModel): boolean;
/**
 * OPTIONAL per-request facts for {@link resolveReasoning} — what the wire's budget arm knows at
 * request build that a per-leg eager resolution cannot: the resolved output cap and whether it is a
 * HARD bound. Supplied ⇒ the anthropic budget arm mirrors the wire's cap-wins skip
 * ({@link budgetCapSkipsThinking}); absent ⇒ the budget arm reports the cap-blind gradient it always
 * did (an eager mint that has not yet seen a request has no facts).
 *
 * Who supplies them, and why it is never the reporting caller's own arithmetic: the adapter
 * that BUILT the request reports the pair it judged, through the runner's reasoning-wire-facts sink
 * (`status-sink.ts`), from its `onCommitted` hook so a speculatively-built request the overflow
 * recovery declined can never be reported as sent. A consumer re-deriving the cap would have to
 * re-implement the adapter's precedence chain (engine override > caller `options.maxTokens` >
 * `model.maxTokens` > brain-construction default) — a second source of truth for a number only the
 * minter can state. The runner then re-resolves with them: the skip and its report stay ONE predicate
 * reading ONE set of facts.
 */
export interface ReasoningWireFacts {
    /** The request's resolved output cap (the wire `max_tokens` at the moment the thinking arm judges). */
    outputCapTokens: number;
    /** True when the cap is HARD (engine override / caller `options.maxTokens`) — the lanes the brain
     *  refuses to raise; a soft model/config cap is raised to host the budget instead. */
    hardOutputCap: boolean;
}
/**
 * The anthropic-`effortLevels` PRESENCE/SHAPE gate, shared by the wire arm (anthropic.ts) and the
 * reporting dispatch below so the two cannot disagree about which family a request rides (#335): the
 * old twin predicates were `x && x.length > 0` on both sides, so a truthy NON-ARRAY (a string —
 * `.length > 0` holds) entered the wire arm and threw a bare TypeError from its `.filter` pre-clean
 * BEFORE {@link resolveEffort}'s centralized non-array fallback could read it as undeclared — while
 * the reporter happily described an effort resolution for the same config. Only the container shape
 * is judged here; MEMBER validity stays {@link resolveEffort}'s job (its element-level sanitization
 * is the single bad-value seat, which is also why the returned array is not member-checked — the cast
 * is checked at runtime by every consumer's `resolveEffort` call).
 */
export declare function declaredEffortLevels(v: unknown): readonly ThinkingLevel[] | undefined;
/**
 * The effort-lane WIRE-VALUE mint — clamp ({@link resolveEffort}) + the `Model.thinkingLevelMap`
 * translation in ONE place, consumed by both completions-family appliers (openai.ts `applyThinking`,
 * open-responses.ts `resolveWireEffort`) AND the reporting dispatch ({@link resolveReasoning}'s
 * arms), so the value that reaches the wire and the resolution a trace/result face claims are two
 * reads of one computation, never parallel re-derivations. Map semantics (the field's contract): a
 * MISSING key ⇒ provider default (the clamped tier name as-is); a STRING ⇒ that provider-specific
 * spelling (same tier, still honored); `null` ⇒ the tier is UNSUPPORTED on this model —
 * `wireValue: undefined`, no effort value on the wire (thinking still enables via a format's own
 * enable key where one exists), which is exactly the tier-not-honored shape the reporter must echo.
 */
export declare function mintEffortWireValue(requested: ThinkingLevel, model: {
    thinkingLevelMap?: Readonly<Partial<Record<ThinkingLevel, string | null>>>;
}, allowed: readonly ThinkingLevel[] | undefined): {
    resolution: ReasoningResolution;
    wireValue: string | undefined;
};
/**
 * A {@link ReasoningResolution} enriched with the endpoint discriminant, for observability (design/96 S6).
 * The brain consumes only the {@link ReasoningResolution} fields to shape the request; `format`/`endpoint`
 * are reported (e.g. a `reasoning.resolved` trace event) so a deployment can see WHY a tier was downgraded
 * (binary provider) or clamped (effort-set cap) rather than the resolution being silently swallowed (§E honesty).
 */
export interface ResolvedReasoning extends ReasoningResolution {
    /** The wire format the request will use (the load-bearing reason for `graded`/`clamped`). */
    format: ReasoningFormat;
    /** A coarse endpoint label for the trace (`model.api` — e.g. `openai-completions`, `anthropic-messages`). */
    endpoint: string;
    /**
     * Present (true) only when the request never CARRIES at all: {@link reasoningRequestCarried} false
     * on a non-"off" request — the model declares NO reasoning capability (`Model.reasoning` falsy),
     * OR the requested value is not a valid {@link ThinkingLevel} (an out-of-contract tier every wire
     * applier reads as ABSENCE — the same three-conjunct gate all of them share) — or, with
     * {@link ReasoningWireFacts} supplied, the anthropic budget path's cap-wins skip
     * ({@link budgetCapSkipsThinking}), so NO thinking
     * parameter reaches the wire at all — the requested tier is DROPPED entirely, not clamped or
     * downgraded-to-binary. `effective:"off"` here states the ENGINE side of that fact (nothing was
     * requested), NOT a measured gateway state: on the binary enable-only formats (qwen / zai /
     * qwen-chat-template) parameter ABSENCE is provider-default, and a default-on gateway may still
     * reason at its own tier — the brains deliberately send no disable key for a model declared
     * non-reasoning, so the engine cannot claim a measured off there; `format` tells a consumer which
     * family applies (on every other format, absence is the closest the wire has to off — see
     * applyThinking's own contract). `format`/`endpoint` report the family that WOULD have carried the
     * tier (the why-shape a consumer diagnoses with, not a claim about the request). Absent on every
     * reasoning-capable resolution, so existing consumers see byte-identical objects. Loud-bad-values
     * rule: the one arm where the request evaporates must not be the one arm with no report.
     */
    dropped?: true;
}
/**
 * Resolve a requested intensity against a model END-TO-END, dispatching on its wire format the SAME way the
 * brains do — so a trace event and the actual provider request can never drift (design/96 S6). This is the
 * single observability-side resolver: the runner calls it at task start to emit `reasoning.resolved`; the
 * brains keep calling {@link resolveEffort}/{@link resolveBinary}/{@link reasoningBudgetShare} on the hot path.
 *
 * - Anthropic (`api === "anthropic-messages"`) → budget-based: the tier sets a budget share, so it's a real
 *   gradient (`graded:true`) and never tier-clamped (`clamped:false`); reported as `format:"budget"`. With
 *   the optional {@link ReasoningWireFacts} the arm additionally mirrors the wire's cap-wins skip
 *   ({@link budgetCapSkipsThinking}: a hard per-request output cap < 2·{@link MIN_THINKING_TOKENS} deletes
 *   the thinking block) as the drop shape — facts absent keeps the historic cap-blind gradient.
 * - Binary enable-only formats (qwen / zai / qwen-chat-template) → `graded:false` (tier not honored).
 * - An effort endpoint with `supportsReasoningEffort:false` → `graded:false` (enable key only, no effort tier).
 * - Otherwise effort-based → clamp DOWN to the endpoint's `reasoningEffortLevels` (default minimal|low|medium|high).
 * - A CLAMPED tier that `model.thinkingLevelMap` maps to `null` (declared unsupported on this model) →
 *   `graded:false`: both effort-wire appliers key the map by the post-clamp tier and then carry NO effort
 *   value (thinking still enables via the format's own enable key where one exists), so the tier is not
 *   honored. A resolver blind to the map reports such a request as exactly honored while the wire
 *   drops the value — trace/result-face drift.
 *
 * - A request that never CARRIES ({@link reasoningRequestCarried} false on a non-"off" value: the model's
 *   `reasoning` capability flag is FALSY, or the requested value is not a valid tier — no brain emits any
 *   thinking parameter for either, whatever the format) → `effective:"off"`, `graded:false`, `clamped:true`,
 *   `dropped:true` — the loud-drop arm. Describing the capability dispatch instead would report a
 *   resolution the request never carried, leaving the one arm where the request evaporates as the one
 *   arm with no disclosure (and an out-of-contract tier reported as a clamped gradient, or echoed as
 *   `effective` on the binary formats, while the wire carried nothing).
 *
 * `off`/falsy never enables thinking, so it resolves trivially (no clamp, graded:true) — the caller decides
 * whether to emit at all.
 */
export declare function resolveReasoning(requested: ThinkingLevel, model: {
    api?: string;
    reasoning?: boolean;
    compat?: unknown;
    thinkingLevelMap?: Readonly<Partial<Record<ThinkingLevel, string | null>>>;
}, facts?: ReasoningWireFacts): ResolvedReasoning;
/**
 * Resolve a requested intensity for an effort-based endpoint (`reasoning_effort` / `reasoning.effort`). Picks
 * the requested tier when supported; otherwise the highest supported tier ≤ requested (clamp DOWN, never
 * silently up); if none is ≤ requested (the endpoint's set is entirely higher — unusual), the lowest supported
 * tier. Never returns a value outside `allowed`, so the brain can't emit a tier the endpoint would 422.
 * A malformed `allowed` reads as UNDECLARED → the conservative default set (non-array, empty, or no
 * valid member); individually invalid MEMBERS (garbage strings, sparse holes, `"off"` — not a legal
 * member of the 6-tier compat effort sets) are dropped, so they can never become a clamp target.
 */
/**
 * #692 C-c — the effort tiers that actually REACH THE WIRE for this model: the table {@link resolveEffort} clamps
 * against, keyed by the model's API family exactly as {@link resolveReasoning} dispatches, gated by the request
 * entry predicate (a `reasoning: false` model accepts no tier) and minus the tiers the model's `thinkingLevelMap`
 * suppresses (`null` = no effort value on the wire) — the same arms, so a host reading this and the trace's
 * `effective` can never disagree:
 *  - `anthropic-messages` with declared `compat.effortLevels` → that set (the `output_config.effort` lane);
 *    without it → `undefined` (the BUDGET lane is a token gradient, there is no tier set to clamp to);
 *  - the Responses family and the completions family → `compat.reasoningEffortLevels` sanitized
 *    (invalid members dropped, an empty/garbage declaration reads as undeclared) or the conservative
 *    {@link DEFAULT_EFFORT_LEVELS}; `supportsReasoningEffort: false` (openrouter excepted, whose unified
 *    knob ignores it) and the binary formats (`qwen` / `zai` / `qwen-chat-template`) → `undefined` (the tier
 *    is not honored as a gradient on that wire).
 * `undefined` therefore means "this wire clamps no tier set", never "unknown": a host that offers a person the
 * supported tiers reads THIS, per model, instead of a global default it cannot vouch for. Per API, not per
 * model id: the acceptance set is a property of the endpoint's request schema; `Model` grows no key for it.
 */
export declare function reasoningEffortLevelsOf(model: {
    api?: string;
    reasoning?: boolean;
    compat?: unknown;
    thinkingLevelMap?: Readonly<Partial<Record<ThinkingLevel, string | null>>>;
}): readonly ThinkingLevel[] | undefined;
export declare function resolveEffort(requested: ThinkingLevel, allowed?: readonly ThinkingLevel[]): ReasoningResolution;
/**
 * Resolve a requested intensity for a binary enable-only endpoint (qwen / zai / qwen-chat-template): the
 * provider only takes an on/off switch, so the intensity tier is NOT honored as a gradient. `graded: false`
 * is the load-bearing honesty signal.
 */
export declare function resolveBinary(requested: ThinkingLevel): ReasoningResolution;
/**
 * Extended-thinking budget as a FRACTION of `max_tokens` per intensity tier, for budget-based endpoints
 * (Anthropic). Lets a higher intensity actually buy a larger thinking budget — before this, the budget was a
 * fixed share regardless of the requested tier, so the intensity had no effect on Anthropic (design/96 §D/§E).
 * The brain clamps the resulting budget to Anthropic's `[1024, max_tokens-1]` window; an explicit
 * `thinkingBudgetTokens` / `thinkingBudgetShare` in config still overrides this table.
 */
export declare const REASONING_BUDGET_SHARE: Record<ThinkingLevel, number>;
/** The extended-thinking budget share for a given intensity tier (see {@link REASONING_BUDGET_SHARE}). */
export declare function reasoningBudgetShare(level: ThinkingLevel): number;
/**
 * design/96 §D (S4) — a user-facing NAMED reasoning tier, DISTINCT from the raw 7-tier {@link ThinkingLevel}
 * ({@link ReasoningIntensity}). A profile maps it to engine flags via {@link resolveReasoningProfile}. This is
 * the "ultracode" parity axis: a high tier (`ultra`) buys both a higher thinking level AND a thoroughness/
 * self-verify prompt nudge.
 */
export type ReasoningTier = "off" | "fast" | "standard" | "deep" | "ultra";
/** The engine flags a {@link ReasoningTier} resolves to (design/96 §D table). A profile may override the
 *  default; core ships sane defaults. */
export interface ReasoningProfileFlags {
    /** The vendor thinking level to run at (clamped per-endpoint downstream by {@link resolveEffort}). */
    thinking: ThinkingLevel;
    /**
     * Compose `ORCHESTRATION_AWARENESS` — a high-tier thoroughness/self-verify nudge. 🔴 NOT the `run_workflow`
     * tool (that is gated by a hard sandbox, S8 §6.3); this is purely about how the model reasons. Independent
     * of self-orchestration (a task can be both).
     */
    awarenessGuidance: boolean;
    /** Advisory HINT that goal mode suits this tier. Core NEVER forces intensity→mode (constitution: the
     *  mapping is profile data); a profile/caller decides whether to actually run `runGoal`. */
    goalSuggested: boolean;
}
/**
 * design/96 §D (S4) — map a named {@link ReasoningTier} to its engine {@link ReasoningProfileFlags} (default
 * mapping). G2: the intensity→capability mapping is PROFILE-layer data — core gives this primitive +
 * a sane default; a profile/scenario layer calls it (and may override the table) to set a task's `thinking` +
 * prompt flags. Core never forces it. Returns a fresh COPY (callers may mutate).
 */
export declare function resolveReasoningProfile(tier: ReasoningTier): ReasoningProfileFlags;
