import type { ThinkingLevel } from "../internal/harness.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; /** 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"; /** 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, or an effort endpoint that declares * `supportsReasoningEffort:false`): 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; } /** * 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; } /** * 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"`. * - 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). * * `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; }): 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. */ 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; /** 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 (clay): 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; //# sourceMappingURL=reasoning.d.ts.map