/** * User-facing model + thinking-level selection. * * Extracted verbatim from agent-session.ts (god-file decomposition). Owns the manual/explicit model * switch and cycle paths and the thinking-level set/cycle/clamp — the deliberate human choices, as * opposed to the per-turn auto-routing owned by ModelRouterController. It mutates `agent.state.model` * / `agent.state.thinkingLevel` through deps and re-derives the capability-scoped tool surface, but the * session keeps the `model`/`thinkingLevel` GETTERS so the drive loop's reads are untouched. Model * choice is advisory-only: it warns on a bad-fit fitness probe or an oversized local model, never blocks. */ import type { Agent, ThinkingLevel } from "@caupulican/pi-agent-core"; import type { SessionManager } from "@caupulican/pi-agent-core/node"; import type { Api, Model } from "@caupulican/pi-ai"; import type { AgentSessionEvent, ModelCycleResult } from "./agent-session-contracts.ts"; import type { ExtensionRunner } from "./extensions/index.ts"; import type { ModelCapabilityProfile } from "./model-capability.ts"; import type { ModelRegistry } from "./model-registry.ts"; import type { OllamaRuntime } from "./models/local-runtime.ts"; import type { SettingsManager } from "./settings-manager.ts"; export interface ModelSelectionControllerDeps { getAgent(): Agent; getModel(): Model | undefined; getThinkingLevel(): ThinkingLevel; getModelRegistry(): ModelRegistry; getSessionManager(): SessionManager; getSettingsManager(): SettingsManager; getExtensionRunner(): ExtensionRunner; getAgentDir(): string; /** Scoped models (--models flag), used by the cycle path. */ getScopedModels(): Array<{ model: Model; thinkingLevel?: ThinkingLevel; }>; /** The user-requested active tool set, re-applied when the model's capability class changes. */ getRequestedActiveToolNames(): string[] | undefined; getActiveToolNames(): string[]; setActiveToolsByName(toolNames: string[]): void; getModelCapabilityProfile(): ModelCapabilityProfile; /** Rebuild the base prompt after a live orchestration-level change without altering requested tools. */ refreshBaseSystemPrompt(): void; /** Session event emit (warnings + thinking_level_changed; model_select goes via the extension runner). */ emit(event: AgentSessionEvent): void; /** Context-window-usage warning check (session-owned, compaction-adjacent). */ checkContextWindowUsageWarning(): void; /** Resolve the Ollama server URL for a model base URL (local-runtime controller). */ deriveOllamaServerUrl(modelBaseUrl: string): string; /** Local Ollama runtime for the given server URL (used for the oversized-model risk check). */ getLocalRuntime(serverUrl: string): OllamaRuntime; } export declare class ModelSelectionController { private readonly deps; constructor(deps: ModelSelectionControllerDeps); private _emitModelSelect; /** * Set model directly. * Validates that auth is configured, saves to session and settings. * @throws Error if no auth is configured for the model */ setModel(model: Model, options?: { persistSettings?: boolean; }): Promise; private _resyncToolSurfaceForModel; /** * Manual model choice is a deliberate human decision, not an auto-adoption flow — it is * ADVISORY ONLY: warn on evidence the model is a bad fit, but never block and never prompt * (print/RPC modes only ever see plain warning text through the existing `warning` event, the * same channel `_checkContextWindowUsageWarning` above uses). Two independent checks, both * best-effort: * - a recorded all-lanes-failed fitness probe on THIS host (see `isProbeAllFailed`); * - for an Ollama-served local model, weights that exceed ~90% of total system memory, which * is the exact failure the OOM report reproduced (llama-server needs the whole model resident). */ private _warnIfManualModelChoiceIsRisky; /** * Cycle to next/previous model. * Uses scoped models (from --models flag) if available, otherwise all available models. * @param direction - "forward" (default) or "backward" * @returns The new model info, or undefined if only one model available */ cycleModel(direction?: "forward" | "backward"): Promise; private _cycleScopedModel; private _cycleAvailableModel; /** * Set thinking level. * Clamps to model capabilities based on available thinking levels. * Saves to session and settings only if the level actually changes. */ setThinkingLevel(level: ThinkingLevel, options?: { persistSettings?: boolean; }): void; /** * Cycle to next thinking level. * @returns New level, or undefined if model doesn't support thinking */ cycleThinkingLevel(): ThinkingLevel | undefined; /** * Get available thinking levels for current model. * The provider will clamp to what the specific model supports internally. */ getAvailableThinkingLevels(): ThinkingLevel[]; /** * Check if current model supports thinking/reasoning. */ supportsThinking(): boolean; private _getThinkingLevelForModelSwitch; private _clampThinkingLevel; } //# sourceMappingURL=model-selection-controller.d.ts.map