UNPKG

capsule-ai-cli

Version:

The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing

223 lines 8.58 kB
import { configManager } from '../core/config.js'; import { openRouterModelsService } from './openrouter-models.js'; import { localModelsService } from './local-models.js'; export class StateService { state; DEFAULT_STATE = { currentModel: 'openai/gpt-4o', currentProvider: 'openai', currentMode: 'agent', commandHistory: [], historyIndex: -1, maxHistorySize: 100, licenseStatus: undefined }; constructor() { this.state = this.loadState(); } loadState() { const config = configManager.getConfig(); const savedState = config.state || {}; let mode = savedState.currentMode || this.DEFAULT_STATE.currentMode; if (mode === 'chat') mode = 'agent'; if (mode === 'fusion') mode = 'orchestrator'; return { ...this.DEFAULT_STATE, currentModel: savedState.currentModel || config.providers[savedState.currentProvider || 'openai']?.defaultModel || this.DEFAULT_STATE.currentModel, currentProvider: savedState.currentProvider || config.defaultProvider || this.DEFAULT_STATE.currentProvider, currentMode: mode, commandHistory: savedState.commandHistory || [], historyIndex: -1 }; } saveState() { const { historyIndex, ...stateToSave } = this.state; configManager.setConfig('state', stateToSave); } setModel(model) { this.state.currentModel = model; this.saveState(); } getModel() { return this.state.currentModel; } setProvider(provider) { this.state.currentProvider = provider; const models = this.getAvailableModelsSync(provider); if (models.length > 0) { this.state.currentModel = models[0]; } this.saveState(); } getProvider() { return this.state.currentProvider; } setMode(mode) { this.state.currentMode = mode; if (!openRouterModelsService.isModelAvailable(this.state.currentModel, mode)) { const models = this.getAvailableModelsSync(this.state.currentProvider); if (models.length > 0) { this.state.currentModel = models[0]; } } this.saveState(); } getMode() { return this.state.currentMode; } setLicenseStatus(status) { this.state.licenseStatus = status; } getLicenseStatus() { return this.state.licenseStatus; } addToHistory(command) { if (this.state.commandHistory.length > 0 && this.state.commandHistory[this.state.commandHistory.length - 1] === command) { return; } this.state.commandHistory.push(command); if (this.state.commandHistory.length > this.state.maxHistorySize) { this.state.commandHistory = this.state.commandHistory.slice(-this.state.maxHistorySize); } this.state.historyIndex = -1; this.saveState(); } getPreviousCommand() { if (this.state.commandHistory.length === 0) return null; if (this.state.historyIndex === -1) { this.state.historyIndex = this.state.commandHistory.length - 1; } else if (this.state.historyIndex > 0) { this.state.historyIndex--; } return this.state.commandHistory[this.state.historyIndex]; } getNextCommand() { if (this.state.commandHistory.length === 0) return null; if (this.state.historyIndex === -1) return null; if (this.state.historyIndex < this.state.commandHistory.length - 1) { this.state.historyIndex++; return this.state.commandHistory[this.state.historyIndex]; } else { this.state.historyIndex = -1; return ''; } } getHistory() { return [...this.state.commandHistory]; } clearHistory() { this.state.commandHistory = []; this.state.historyIndex = -1; this.saveState(); } async getAvailableModels(provider) { if (['local', 'ollama', 'lmstudio', 'llamacpp'].includes(provider)) { return localModelsService.getAvailableModels(); } try { await openRouterModelsService.fetchModels(false, true); const models = openRouterModelsService.getModelsByProvider(provider); return models.map(m => m.id); } catch (error) { console.error('Failed to fetch models:', error); const fallbackModels = { openai: ['openai/gpt-4o', 'openai/gpt-4o-mini'], anthropic: ['anthropic/claude-opus-4', 'anthropic/claude-sonnet-4'], google: ['google/gemini-2.5-pro', 'google/gemini-2.5-flash'], xai: ['x-ai/grok-4'], deepseek: ['deepseek/deepseek-chat-v3-0324', 'deepseek/deepseek-r1-0528:free'], moonshot: ['moonshotai/kimi-k2'] }; return fallbackModels[provider] || []; } } getAvailableModelsSync(provider) { if (['local', 'ollama', 'lmstudio', 'llamacpp'].includes(provider)) { return localModelsService.getAvailableModels(); } const models = openRouterModelsService.getModelsByProvider(provider); if (models.length > 0) { return models.map(m => m.id); } const fallbackModels = { openai: ['openai/gpt-4o', 'openai/gpt-4o-mini'], anthropic: ['anthropic/claude-opus-4', 'anthropic/claude-sonnet-4'], google: ['google/gemini-2.5-pro', 'google/gemini-2.5-flash'], xai: ['x-ai/grok-4'], deepseek: ['deepseek/deepseek-chat-v3-0324', 'deepseek/deepseek-r1-0528:free'], moonshot: ['moonshotai/kimi-k2'] }; return fallbackModels[provider] || []; } async getAvailableProviders() { const providers = []; if (await localModelsService.isAnyServerAvailable()) { const serverStatus = localModelsService.getServerStatus(); for (const server of serverStatus) { if (server.available) { if (server.name === 'Ollama') providers.push('ollama'); else if (server.name === 'LM Studio') providers.push('lmstudio'); else if (server.name === 'llama.cpp') providers.push('llamacpp'); } } if (providers.length > 0 && !providers.includes('local')) { providers.unshift('local'); } } const config = configManager.getConfig(); if (config.providers.openrouter?.apiKey) { try { await openRouterModelsService.fetchModels(); const openRouterProviders = openRouterModelsService.getAvailableProviders(); providers.push(...openRouterProviders); } catch (error) { console.error('Failed to fetch providers:', error); providers.push('openai', 'anthropic', 'google', 'xai', 'deepseek', 'moonshot'); } } return [...new Set(providers)]; } getAvailableProvidersSync() { const providers = []; const serverStatus = localModelsService.getServerStatus(); for (const server of serverStatus) { if (server.available) { if (server.name === 'Ollama') providers.push('ollama'); else if (server.name === 'LM Studio') providers.push('lmstudio'); else if (server.name === 'llama.cpp') providers.push('llamacpp'); } } if (providers.length > 0 && !providers.includes('local')) { providers.unshift('local'); } const config = configManager.getConfig(); if (config.providers.openrouter?.apiKey) { const openRouterProviders = openRouterModelsService.getAvailableProviders(); if (openRouterProviders.length > 0) { providers.push(...openRouterProviders); } else { providers.push('openai', 'anthropic', 'google', 'xai', 'deepseek', 'moonshot'); } } return [...new Set(providers)]; } } export const stateService = new StateService(); //# sourceMappingURL=state.js.map