import type { LocalProviderDefinition, LocalProviderRuntimeOptions, RuntimeModelReference, SandboxPolicy } from "@mono-agent/runtime-adapter"; /** * Per-request runtime-options extension that applies a per-turn model/effort * override carried on webhook (`metadata.webhook`), cron (`metadata.cron`), or * web console (`metadata.web`), interactive TUI (`metadata.tui`), Telegram * (`metadata.telegram`), or Slack (`metadata.slack`) request metadata — an operator can pick model/effort * just as a trigger can pin one. The * adapters carry the override as raw strings; this is the * first place with both the model parser and the effort enum, so validation * lives here. An invalid value is WARNED and IGNORED (the turn falls back to the * harness default) rather than failing — a bad dynamic webhook `model` must not * 500 the request. * * The extension ALSO scans every turn's message text for effort trigger * phrases ("think"/"extra think"/"ultra think") and escalates the turn's * effort — see `applyEffortKeywordEscalation`. This lives here rather than in * a sibling extension because siblings compose later-wins in parallel: only * this extension knows the metadata effort the keyword must be compared * against (escalation-only), and it already owns the direct-OpenCode guard. * Effort-only writes keep the shared session (the harness isolates on MODEL * overrides only). * * Execution mode is NOT set here: the harness derives it from the effective model * plus the host's configured executionMode (keeping a compatible host mode, e.g. * claude in `cli`, and only falling back to the model default for an incompatible * one, e.g. a `codex:*` override under an `sdk` host). * * A model override OWNS the local-provider endpoint block. Whenever a VALID model * override is applied, this extension SETS the four endpoint fields * (`customProvider`/`customModel`/`modelCapabilities`/`isPrivateProvider`): * - LOCAL override (`sdk === "pi"` with a configured provider id): recompute the * block for the OVERRIDE model via `runtimeOptionsForLocalProvider`. * - CLOUD/registry override, an UNCONFIGURED local provider id, or a * misconfigured provider: set the four fields to `null` to explicitly CLEAR * the host default's block. * This is required because the host default block is computed ONCE from * `config.runtime.model` at harness creation, and the pi runtime routes on * `customProvider` PRESENCE alone — so a cloud override under an all-LOCAL default * would otherwise inherit the default's local endpoint and send the cloud model to * localhost (same mis-route for an unconfigured local provider id). The harness * `mergeRuntimeOptions` applies the override AFTER the host default * (last-writer-wins) and reads `null` on these keys as "delete", so a set block * REPLACES the default and a null CLEARS it. An effort-only / no-model turn leaves * the block untouched (the default's block is correct for the default model). */ export interface RequestModelOverrideLogger { warn?(message: string, metadata?: Record): void; info?(message: string, metadata?: Record): void; } export interface RequestModelOverrideOptions { readonly logger?: RequestModelOverrideLogger; /** Host primary used to prevent unsafe direct-Codex ↔ non-Codex family changes. */ readonly baseModel?: RuntimeModelReference; /** Host fallback chain retained behind a request-level primary override. */ readonly fallbackModels?: readonly RuntimeModelReference[]; /** Host effort inherited by model-only overrides unless the override supplies one. */ readonly baseEffort?: string; /** Host hard turn cap inherited by request-level model overrides. */ readonly baseMaxTurns?: number; /** Effective configured/auto-provisioned MCP sources inherited by the turn. */ readonly mcpSources?: readonly string[]; /** Whether progressive index disclosure would inject runtime skill metadata. */ readonly indexSkillsActive?: boolean; /** * Host mono-agent sandbox policy. Claude and direct OpenCode provider-owned * tool loops do not consume this policy, so a request cannot dynamically * switch to either runtime while a non-off policy is active. */ readonly sandboxPolicy?: Pick; /** Effective host tool policy used to reject direct OpenCode overrides it cannot enforce. */ readonly toolPolicy?: { readonly allowedTools: readonly string[]; readonly disallowedTools: readonly string[]; }; /** * Configured local providers (`config.providers?.local`). When an override * names a model one of these serves, the extension recomputes the provider * endpoint block so the override reaches the right local endpoint instead of * inheriting the host default's block. */ readonly localProviders?: readonly LocalProviderDefinition[]; } interface RequestModelOverrideInput { readonly request: { readonly metadata?: Record; readonly userMessage?: string; }; } interface RequestModelOverrideResult { readonly runtimeOptions: { model?: RuntimeModelReference; effort?: string; customProvider?: LocalProviderRuntimeOptions["customProvider"] | null; customModel?: LocalProviderRuntimeOptions["customModel"] | null; modelCapabilities?: LocalProviderRuntimeOptions["modelCapabilities"] | null; isPrivateProvider?: LocalProviderRuntimeOptions["isPrivateProvider"] | null; }; readonly cleanup: () => Promise; } export declare function createRequestModelOverrideRuntimeExtension(options?: RequestModelOverrideOptions): (input: RequestModelOverrideInput) => Promise; /** * Whether the request-level override will actually switch this turn to direct * OpenCode under the supplied host constraints. Adapter MCP injection uses the * same decision as the model extension: a merely parseable OpenCode string is * not enough, because a sandbox/tool/MCP/effort/turn-cap rejection must retain * both the Pi model and its interaction tools. */ export declare function requestModelOverrideTargetsDirectOpenCode(metadata: Record | undefined, options?: RequestModelOverrideOptions): boolean; /** Whether the accepted per-request route lacks a request-scoped host MCP seam. */ export declare function requestModelOverrideTargetsUnsupportedHistoryTool(metadata: Record | undefined, options?: RequestModelOverrideOptions): boolean; /** Whether the accepted request route (or its configured base) is Pi-native. */ export declare function requestModelOverrideTargetsPiNative(metadata: Record | undefined, options?: RequestModelOverrideOptions): boolean; /** * Whether every route the configured fallback router can reach for this * request is Pi-native. ProcessJobs private-state protection requires this * stronger contract: a single non-Pi primary or fallback would move execution * to a provider-owned tool loop that cannot enforce the mono-agent sandbox. * * Keep this separate from `requestModelOverrideTargetsPiNative`, whose * intentionally permissive any-Pi meaning is used by other capability * discovery. The chain projection mirrors `fallbackChainForConfig`: an * accepted request override replaces the primary and a configured fallback * equal to that effective primary is skipped without otherwise rewriting the * configured order. Missing, malformed, or duplicate reachable routes fail * closed — and a resolution failure is WARNED rather than discarded, so it can * be told apart from a genuine non-Pi route. */ export declare function requestModelOverrideRoutesOnlyPiNative(metadata: Record | undefined, options?: RequestModelOverrideOptions): boolean; export {}; //# sourceMappingURL=request-model-override.d.ts.map