/**
 * ModelManager — model switching, cycling, and thinking level management.
 *
 * Validates API keys, persists changes to SessionManager + SettingsManager.
 *
 * Stable deps (agent, registries, managers) are constructor-injected.
 * Part of the AgentSession extracted modules.
 */
import { clampThinkingLevel, computeNextModel, cycleThinkingLevel as computeNextThinkingLevel, getAvailableThinkingLevels } from './session-models.js';
// ============================================================================
// Manager
// ============================================================================
export class ModelManager {
    _agent;
    _modelRegistry;
    _sessionManager;
    _settingsManager;
    constructor(_agent, _modelRegistry, _sessionManager, _settingsManager) {
        this._agent = _agent;
        this._modelRegistry = _modelRegistry;
        this._sessionManager = _sessionManager;
        this._settingsManager = _settingsManager;
    }
    /** Set a specific model. Validates API key and persists. */
    async setModel(model) {
        await this._validateApiKey(model);
        this._applyAndPersist(model);
        this.setThinkingLevel(this._agent.state.thinkingLevel);
    }
    /** Cycle to the next available model. Returns result or undefined if none available. */
    async cycleModel(direction = 'forward') {
        const available = await this._modelRegistry.getAvailable();
        const next = computeNextModel(available, this._agent.state.model, direction);
        if (!next)
            return undefined;
        await this._validateApiKey(next);
        this._applyAndPersist(next);
        this.setThinkingLevel(this._agent.state.thinkingLevel);
        return { model: next, thinkingLevel: this._agent.state.thinkingLevel };
    }
    /**
     * Restore a model from session persistence. Sets model on agent
     * but does NOT persist (data already exists in session).
     */
    async restoreModel(model) {
        this._agent.setModel(model);
    }
    /** Set thinking level, clamped to model capabilities. Persists only on change. */
    setThinkingLevel(level) {
        const effective = clampThinkingLevel(level, getAvailableThinkingLevels(this._agent.state.model));
        const isChanging = effective !== this._agent.state.thinkingLevel;
        this._agent.setThinkingLevel(effective);
        if (isChanging) {
            this._sessionManager.appendThinkingLevelChange(effective);
            this._settingsManager.setDefaultThinkingLevel(effective);
        }
    }
    /** Cycle to the next thinking level. Returns new level, or undefined if not supported. */
    cycleThinkingLevel() {
        const next = computeNextThinkingLevel(this._agent.state.thinkingLevel, this._agent.state.model);
        if (next === undefined)
            return undefined;
        this.setThinkingLevel(next);
        return next;
    }
    // --------------------------------------------------------------------------
    // Internal
    // --------------------------------------------------------------------------
    async _validateApiKey(model) {
        const apiKey = await this._modelRegistry.getApiKey(model);
        if (!apiKey)
            throw new Error(`No API key for ${model.provider}/${model.id}`);
    }
    _applyAndPersist(model) {
        this._agent.setModel(model);
        this._sessionManager.appendModelChange(model.provider, model.id);
        this._settingsManager.setDefaultModelAndProvider(model.provider, model.id);
    }
}
//# sourceMappingURL=model-manager.js.map