1 line
187 KiB
JSON
1 line
187 KiB
JSON
{"repo": "axpdev-lab/aeroftp", "files": {"src/types/ai.ts": {"6b442911c82f0a99adcdfe39b828e373c9640076": {"t": 1785746025.528968, "n": 8681, "h": "c035ec6c4d1c6084", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet: AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks' | 'nvidia' | 'zai' | 'hyperbolic' | 'novita' | 'yi' | 'kilo';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n responseStyle?: 'default' | 'concise' | 'explanatory' | 'learning'; // CC-10 output style persona\n };\n defaultModelId: string | null;\n}\n\n// OPT-06: the canonical chat message type is `Message` in\n// `components/DevTools/aiChatTypes.ts`; the SQLite persistence shape is\n// `ChatMessage` in `utils/chatHistory.ts`. The orphan `ChatMessage`/`ToolCall`\n// interfaces that used to live here had zero importers and were removed.\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'NVIDIA NIM',\n type: 'nvidia',\n baseUrl: 'https://integrate.api.nvidia.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Z.AI (Zhipu)',\n type: 'zai',\n baseUrl: 'https://api.z.ai/api/paas/v4',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Hyperbolic',\n type: 'hyperbolic',\n baseUrl: 'https://api.hyperbolic.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Novita AI',\n type: 'novita',\n baseUrl: 'https://api.novita.ai/v3/openai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Yi (01.AI)',\n type: 'yi',\n baseUrl: 'https://api.lingyiwanwu.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kilo (Gateway)',\n type: 'kilo',\n baseUrl: 'https://api.kilo.ai/api/gateway',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty: users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n nvidia: [],\n zai: [],\n hyperbolic: [],\n novita: [],\n yi: [],\n kilo: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "74cea07b468e6008edef371bbad0c50a14a62bab": {"t": 1785758930.0491688, "n": 8681, "h": "c035ec6c4d1c6084", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet: AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks' | 'nvidia' | 'zai' | 'hyperbolic' | 'novita' | 'yi' | 'kilo';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n responseStyle?: 'default' | 'concise' | 'explanatory' | 'learning'; // CC-10 output style persona\n };\n defaultModelId: string | null;\n}\n\n// OPT-06: the canonical chat message type is `Message` in\n// `components/DevTools/aiChatTypes.ts`; the SQLite persistence shape is\n// `ChatMessage` in `utils/chatHistory.ts`. The orphan `ChatMessage`/`ToolCall`\n// interfaces that used to live here had zero importers and were removed.\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'NVIDIA NIM',\n type: 'nvidia',\n baseUrl: 'https://integrate.api.nvidia.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Z.AI (Zhipu)',\n type: 'zai',\n baseUrl: 'https://api.z.ai/api/paas/v4',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Hyperbolic',\n type: 'hyperbolic',\n baseUrl: 'https://api.hyperbolic.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Novita AI',\n type: 'novita',\n baseUrl: 'https://api.novita.ai/v3/openai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Yi (01.AI)',\n type: 'yi',\n baseUrl: 'https://api.lingyiwanwu.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kilo (Gateway)',\n type: 'kilo',\n baseUrl: 'https://api.kilo.ai/api/gateway',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty: users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n nvidia: [],\n zai: [],\n hyperbolic: [],\n novita: [],\n yi: [],\n kilo: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "6430fdb2290fa14d88e0ff37f74ca32fe4d4d7ae": {"t": 1785758931.7471294, "n": 8487, "h": "3be6b368b18307a8", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet: AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks' | 'nvidia' | 'zai' | 'hyperbolic' | 'novita' | 'yi';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n responseStyle?: 'default' | 'concise' | 'explanatory' | 'learning'; // CC-10 output style persona\n };\n defaultModelId: string | null;\n}\n\n// OPT-06: the canonical chat message type is `Message` in\n// `components/DevTools/aiChatTypes.ts`; the SQLite persistence shape is\n// `ChatMessage` in `utils/chatHistory.ts`. The orphan `ChatMessage`/`ToolCall`\n// interfaces that used to live here had zero importers and were removed.\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'NVIDIA NIM',\n type: 'nvidia',\n baseUrl: 'https://integrate.api.nvidia.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Z.AI (Zhipu)',\n type: 'zai',\n baseUrl: 'https://api.z.ai/api/paas/v4',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Hyperbolic',\n type: 'hyperbolic',\n baseUrl: 'https://api.hyperbolic.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Novita AI',\n type: 'novita',\n baseUrl: 'https://api.novita.ai/v3/openai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Yi (01.AI)',\n type: 'yi',\n baseUrl: 'https://api.lingyiwanwu.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty: users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n nvidia: [],\n zai: [],\n hyperbolic: [],\n novita: [],\n yi: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "452e1cf2a78a097e4e8bf3076181018a06c25d70": {"t": 1785758933.1317523, "n": 8521, "h": "1b92902f8bf3dd99", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet: AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks' | 'nvidia' | 'zai' | 'hyperbolic' | 'novita' | 'yi';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'NVIDIA NIM',\n type: 'nvidia',\n baseUrl: 'https://integrate.api.nvidia.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Z.AI (Zhipu)',\n type: 'zai',\n baseUrl: 'https://api.z.ai/api/paas/v4',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Hyperbolic',\n type: 'hyperbolic',\n baseUrl: 'https://api.hyperbolic.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Novita AI',\n type: 'novita',\n baseUrl: 'https://api.novita.ai/v3/openai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Yi (01.AI)',\n type: 'yi',\n baseUrl: 'https://api.lingyiwanwu.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty: users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n nvidia: [],\n zai: [],\n hyperbolic: [],\n novita: [],\n yi: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "cbb22f655c2360740ba0f7a0cd06030b1367bfa7": {"t": 1785758934.9930744, "n": 8523, "h": "5fa468e20235e59a", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet — AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks' | 'nvidia' | 'zai' | 'hyperbolic' | 'novita' | 'yi';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'NVIDIA NIM',\n type: 'nvidia',\n baseUrl: 'https://integrate.api.nvidia.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Z.AI (Zhipu)',\n type: 'zai',\n baseUrl: 'https://api.z.ai/api/paas/v4',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Hyperbolic',\n type: 'hyperbolic',\n baseUrl: 'https://api.hyperbolic.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Novita AI',\n type: 'novita',\n baseUrl: 'https://api.novita.ai/v3/openai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Yi (01.AI)',\n type: 'yi',\n baseUrl: 'https://api.lingyiwanwu.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n nvidia: [],\n zai: [],\n hyperbolic: [],\n novita: [],\n yi: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "9ff5ab3b22a87283a082919f45af249881ffbba4": {"t": 1785758936.3560438, "n": 7553, "h": "d4ac8a7e12a3d197", "c": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Copyright (c) 2024-2026 axpnet — AI-assisted (see AI-TRANSPARENCY.md)\n\n// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "e58aef341b31fa745445292303fe64c580ce8fad": {"t": 1785758938.1549408, "n": 7434, "h": "f5ba72090ac6c33b", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n mistral: [],\n groq: [],\n perplexity: [],\n cohere: [],\n together: [],\n ai21: [],\n cerebras: [],\n sambanova: [],\n fireworks: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "7f220d861b062752e09d4a9122213e0716c6ec43": {"t": 1785758940.4529195, "n": 21497, "h": "0b586fe6eacdc8b6", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together' | 'ai21' | 'cerebras' | 'sambanova' | 'fireworks';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'AI21 Labs',\n type: 'ai21',\n baseUrl: 'https://api.ai21.com/studio/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cerebras',\n type: 'cerebras',\n baseUrl: 'https://api.cerebras.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'SambaNova',\n type: 'sambanova',\n baseUrl: 'https://api.sambanova.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Fireworks AI',\n type: 'fireworks',\n baseUrl: 'https://api.fireworks.ai/inference/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n mistral: [\n {\n name: 'mistral-large-latest',\n displayName: 'Mistral Large',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'mistral-small-latest',\n displayName: 'Mistral Small',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'codestral-latest',\n displayName: 'Codestral',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n groq: [\n {\n name: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00059,\n outputCostPer1k: 0.00079,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00005,\n outputCostPer1k: 0.00008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 2,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n perplexity: [\n {\n name: 'sonar-pro',\n displayName: 'Sonar Pro',\n maxTokens: 8192,\n maxContextTokens: 200000,\n inputCostPer1k: 0.003,\n outputCostPer1k: 0.015,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'research'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'sonar',\n displayName: 'Sonar',\n maxTokens: 8192,\n maxContextTokens: 128000,\n inputCostPer1k: 0.001,\n outputCostPer1k: 0.001,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cohere: [\n {\n name: 'command-r-plus',\n displayName: 'Command R+',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0025,\n outputCostPer1k: 0.01,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['rag', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'command-r',\n displayName: 'Command R',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00015,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'rag'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n together: [\n {\n name: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (Together)',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00088,\n outputCostPer1k: 0.00088,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'Qwen/QwQ-32B',\n displayName: 'QwQ 32B (Together)',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0003,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n ai21: [\n {\n name: 'jamba-1.5-large',\n displayName: 'Jamba 1.5 Large',\n maxTokens: 4096,\n maxContextTokens: 262144,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'jamba-1.5-mini',\n displayName: 'Jamba 1.5 Mini',\n maxTokens: 4096,\n maxContextTokens: 262144,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0004,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cerebras: [\n {\n name: 'llama-3.3-70b',\n displayName: 'Llama 3.3 70B (Cerebras)',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00085,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n sambanova: [\n {\n name: 'Meta-Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (SambaNova)',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0006,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'DeepSeek-R1-Distill-Llama-70B',\n displayName: 'DeepSeek R1 Distill 70B (SambaNova)',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0006,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n fireworks: [\n {\n name: 'accounts/fireworks/models/llama-v3p3-70b-instruct',\n displayName: 'Llama 3.3 70B (Fireworks)',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0009,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'accounts/fireworks/models/deepseek-r1',\n displayName: 'DeepSeek R1 (Fireworks)',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.008,\n outputCostPer1k: 0.008,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "068b916a837b8f1d8307afd1a0ce57c5be449f68": {"t": 1785758942.033533, "n": 16645, "h": "3c832cf2105f88f6", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n enableAutoRAGIndexing?: boolean; // B07: opt-in auto-index workspace for RAG context (default: true)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n mistral: [\n {\n name: 'mistral-large-latest',\n displayName: 'Mistral Large',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'mistral-small-latest',\n displayName: 'Mistral Small',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'codestral-latest',\n displayName: 'Codestral',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n groq: [\n {\n name: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00059,\n outputCostPer1k: 0.00079,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00005,\n outputCostPer1k: 0.00008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 2,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n perplexity: [\n {\n name: 'sonar-pro',\n displayName: 'Sonar Pro',\n maxTokens: 8192,\n maxContextTokens: 200000,\n inputCostPer1k: 0.003,\n outputCostPer1k: 0.015,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'research'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'sonar',\n displayName: 'Sonar',\n maxTokens: 8192,\n maxContextTokens: 128000,\n inputCostPer1k: 0.001,\n outputCostPer1k: 0.001,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cohere: [\n {\n name: 'command-r-plus',\n displayName: 'Command R+',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0025,\n outputCostPer1k: 0.01,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['rag', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'command-r',\n displayName: 'Command R',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00015,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'rag'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n together: [\n {\n name: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (Together)',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00088,\n outputCostPer1k: 0.00088,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'Qwen/QwQ-32B',\n displayName: 'QwQ 32B (Together)',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0003,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "4724854c828cdda4fa44db0aab8457bffc8c9df6": {"t": 1785758943.5897145, "n": 16534, "h": "07047130c8e50e43", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n chatHistoryRetentionDays?: number; // 0 = unlimited, 30/60/90/180/365 days\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n mistral: [\n {\n name: 'mistral-large-latest',\n displayName: 'Mistral Large',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'mistral-small-latest',\n displayName: 'Mistral Small',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'codestral-latest',\n displayName: 'Codestral',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n groq: [\n {\n name: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00059,\n outputCostPer1k: 0.00079,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00005,\n outputCostPer1k: 0.00008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 2,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n perplexity: [\n {\n name: 'sonar-pro',\n displayName: 'Sonar Pro',\n maxTokens: 8192,\n maxContextTokens: 200000,\n inputCostPer1k: 0.003,\n outputCostPer1k: 0.015,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'research'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'sonar',\n displayName: 'Sonar',\n maxTokens: 8192,\n maxContextTokens: 128000,\n inputCostPer1k: 0.001,\n outputCostPer1k: 0.001,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cohere: [\n {\n name: 'command-r-plus',\n displayName: 'Command R+',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0025,\n outputCostPer1k: 0.01,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['rag', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'command-r',\n displayName: 'Command R',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00015,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'rag'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n together: [\n {\n name: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (Together)',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00088,\n outputCostPer1k: 0.00088,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'Qwen/QwQ-32B',\n displayName: 'QwQ 32B (Together)',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0003,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "17f767ecd2ed52fde924d553065c159189820a8b": {"t": 1785758945.2645462, "n": 16451, "h": "7923ecac534b14c6", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n mistral: [\n {\n name: 'mistral-large-latest',\n displayName: 'Mistral Large',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'mistral-small-latest',\n displayName: 'Mistral Small',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'codestral-latest',\n displayName: 'Codestral',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n groq: [\n {\n name: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00059,\n outputCostPer1k: 0.00079,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00005,\n outputCostPer1k: 0.00008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 2,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n perplexity: [\n {\n name: 'sonar-pro',\n displayName: 'Sonar Pro',\n maxTokens: 8192,\n maxContextTokens: 200000,\n inputCostPer1k: 0.003,\n outputCostPer1k: 0.015,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'research'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'sonar',\n displayName: 'Sonar',\n maxTokens: 8192,\n maxContextTokens: 128000,\n inputCostPer1k: 0.001,\n outputCostPer1k: 0.001,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cohere: [\n {\n name: 'command-r-plus',\n displayName: 'Command R+',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0025,\n outputCostPer1k: 0.01,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['rag', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'command-r',\n displayName: 'Command R',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00015,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'rag'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n together: [\n {\n name: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (Together)',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00088,\n outputCostPer1k: 0.00088,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'Qwen/QwQ-32B',\n displayName: 'QwQ 32B (Together)',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0003,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "4154efe3b2b10b80b50568a7d11e3b8abb6fdbaf": {"t": 1785758946.627432, "n": 16446, "h": "3282088dc8df2055", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek' | 'mistral' | 'groq' | 'perplexity' | 'cohere' | 'together';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Mistral',\n type: 'mistral',\n baseUrl: 'https://api.mistral.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Groq',\n type: 'groq',\n baseUrl: 'https://api.groq.com/openai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Perplexity',\n type: 'perplexity',\n baseUrl: 'https://api.perplexity.ai',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Cohere',\n type: 'cohere',\n baseUrl: 'https://api.cohere.com/compatibility',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Together AI',\n type: 'together',\n baseUrl: 'https://api.together.xyz/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n mistral: [\n {\n name: 'mistral-large-latest',\n displayName: 'Mistral Large',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.002,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'mistral-small-latest',\n displayName: 'Mistral Small',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0002,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'codestral-latest',\n displayName: 'Codestral',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0009,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n groq: [\n {\n name: 'llama-3.3-70b-versatile',\n displayName: 'Llama 3.3 70B',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00059,\n outputCostPer1k: 0.00079,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast', 'general'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'llama-3.1-8b-instant',\n displayName: 'Llama 3.1 8B Instant',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00005,\n outputCostPer1k: 0.00008,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 2,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n perplexity: [\n {\n name: 'sonar-pro',\n displayName: 'Sonar Pro',\n maxTokens: 8192,\n maxContextTokens: 200000,\n inputCostPer1k: 0.003,\n outputCostPer1k: 0.015,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'research'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'sonar',\n displayName: 'Sonar',\n maxTokens: 8192,\n maxContextTokens: 128000,\n inputCostPer1k: 0.001,\n outputCostPer1k: 0.001,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['search', 'fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n cohere: [\n {\n name: 'command-r-plus',\n displayName: 'Command R+',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0025,\n outputCostPer1k: 0.01,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['rag', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'command-r',\n displayName: 'Command R',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00015,\n outputCostPer1k: 0.0006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'rag'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n together: [\n {\n name: 'meta-llama/Llama-3.3-70B-Instruct',\n displayName: 'Llama 3.3 70B (Together)',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.00088,\n outputCostPer1k: 0.00088,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'Qwen/QwQ-32B',\n displayName: 'QwQ 32B (Together)',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.0003,\n outputCostPer1k: 0.0003,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['reasoning', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "68430fb47791680077ca787048b8dfc4c8e80f7d": {"t": 1785758948.9872363, "n": 9342, "h": "4fa305db70cb600e", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n streamingTimeoutSecs?: number; // Streaming response timeout in seconds (default 120)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [\n {\n name: 'moonshot-v1-8k',\n displayName: 'Moonshot v1 8K',\n maxTokens: 4096,\n maxContextTokens: 8192,\n inputCostPer1k: 0.0012,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'moonshot-v1-128k',\n displayName: 'Moonshot v1 128K',\n maxTokens: 4096,\n maxContextTokens: 131072,\n inputCostPer1k: 0.006,\n outputCostPer1k: 0.006,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['long-context', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n ],\n qwen: [\n {\n name: 'qwen-max',\n displayName: 'Qwen Max',\n maxTokens: 8192,\n maxContextTokens: 32768,\n inputCostPer1k: 0.016,\n outputCostPer1k: 0.064,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 5,\n bestFor: ['reasoning', 'analysis'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'qwen-plus',\n displayName: 'Qwen Plus',\n maxTokens: 8192,\n maxContextTokens: 131072,\n inputCostPer1k: 0.0004,\n outputCostPer1k: 0.0012,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: true,\n supportsThinking: true,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: false,\n },\n {\n name: 'qwen-turbo',\n displayName: 'Qwen Turbo',\n maxTokens: 8192,\n maxContextTokens: 1000000,\n inputCostPer1k: 0.00018,\n outputCostPer1k: 0.00072,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 3,\n bestFor: ['fast'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n deepseek: [\n {\n name: 'deepseek-chat',\n displayName: 'DeepSeek V3',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00014,\n outputCostPer1k: 0.00028,\n supportsStreaming: true,\n supportsTools: true,\n supportsVision: false,\n supportsThinking: false,\n supportsParallelTools: true,\n toolCallQuality: 4,\n bestFor: ['general', 'code'],\n isEnabled: true,\n isDefault: true,\n },\n {\n name: 'deepseek-reasoner',\n displayName: 'DeepSeek R1',\n maxTokens: 8192,\n maxContextTokens: 65536,\n inputCostPer1k: 0.00055,\n outputCostPer1k: 0.0022,\n supportsStreaming: true,\n supportsTools: false,\n supportsVision: false,\n supportsThinking: true,\n supportsParallelTools: false,\n toolCallQuality: 1,\n bestFor: ['reasoning', 'math'],\n isEnabled: true,\n isDefault: false,\n },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "35a7fed19c0a884647136b5c15ce8486fbe8ad2f": {"t": 1785758950.5384374, "n": 5374, "h": "c04b89fe95bfe298", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n webSearchEnabled?: boolean; // Provider web search (Kimi $web_search, Qwen enable_search)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "0ea4cc004ad17f31c35b14ab7e3f0190e17af4e5": {"t": 1785758952.2684026, "n": 5273, "h": "1dfaa8437091fbf9", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom' | 'kimi' | 'qwen' | 'deepseek';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Kimi (Moonshot)',\n type: 'kimi',\n baseUrl: 'https://api.moonshot.cn/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Qwen (Alibaba)',\n type: 'qwen',\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'DeepSeek',\n type: 'deepseek',\n baseUrl: 'https://api.deepseek.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Custom',\n type: 'custom',\n baseUrl: '',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n kimi: [],\n qwen: [],\n deepseek: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "6a1d0144c6e4d7deaec200a80a836c034d703fd1": {"t": 1785758953.8431253, "n": 4541, "h": "a24306f54ffd2ca8", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n maxContextTokens?: number; // Input context window size (distinct from maxTokens output limit)\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n supportsThinking?: boolean; // Extended thinking / chain-of-thought (Claude, o3)\n supportsParallelTools?: boolean; // Multiple tool calls in single response\n toolCallQuality?: 1 | 2 | 3 | 4 | 5; // Tool call accuracy rating\n bestFor?: string[]; // Capability tags\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n topP?: number; // Top-P nucleus sampling (0.0-1.0)\n topK?: number; // Top-K sampling (1-100)\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n thinkingBudget?: number; // Extended thinking budget tokens (0 = disabled, default 10000)\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider (empty — users add their own via Settings or \"Models\" button)\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [],\n openai: [],\n anthropic: [],\n xai: [],\n openrouter: [],\n ollama: [],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "514a4a9eb279b4a2bac0ccd6d3b68025d76d4d15": {"t": 1785758955.0024064, "n": 6443, "h": "da3e5f2a9a2c8b28", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n conversationStyle: 'precise' | 'balanced' | 'creative';\n customSystemPrompt?: string;\n useCustomPrompt?: boolean;\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [\n { name: 'gemini-2.5-flash-preview-05-20', displayName: 'Gemini 2.5 Flash', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'gemini-2.0-flash-exp', displayName: 'Gemini 2.0 Flash', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n { name: 'gemini-1.5-flash', displayName: 'Gemini 1.5 Flash', maxTokens: 32000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n openai: [\n { name: 'gpt-4o', displayName: 'GPT-4o', maxTokens: 128000, inputCostPer1k: 0.005, outputCostPer1k: 0.015, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'gpt-4o-mini', displayName: 'GPT-4o Mini', maxTokens: 128000, inputCostPer1k: 0.00015, outputCostPer1k: 0.0006, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n { name: 'gpt-4-turbo', displayName: 'GPT-4 Turbo', maxTokens: 128000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n anthropic: [\n { name: 'claude-3-5-sonnet-20241022', displayName: 'Claude 3.5 Sonnet', maxTokens: 200000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'claude-3-opus-20240229', displayName: 'Claude 3 Opus', maxTokens: 200000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n xai: [\n { name: 'grok-beta', displayName: 'Grok Beta', maxTokens: 131072, supportsStreaming: true, supportsTools: true, supportsVision: false, isEnabled: true, isDefault: true },\n ],\n openrouter: [\n { name: 'google/gemini-2.0-flash-exp:free', displayName: 'Gemini 2.0 Flash (Free)', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'meta-llama/llama-3.2-3b-instruct:free', displayName: 'Llama 3.2 3B (Free)', maxTokens: 8192, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: false },\n ],\n ollama: [\n { name: 'llama3.2', displayName: 'Llama 3.2', maxTokens: 8192, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: true },\n { name: 'codellama', displayName: 'Code Llama', maxTokens: 4096, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: false },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 9)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}, "580fa65d0e4e140294539b9a725e460821023d45": {"t": 1785758956.3331103, "n": 6371, "h": "612684d6e787fee3", "c": "// AI Provider and Model Types for AeroFTP AI Agent\n\nexport type AIProviderType = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter' | 'ollama' | 'custom';\n\nexport interface AIProvider {\n id: string;\n name: string;\n type: AIProviderType;\n baseUrl: string;\n apiKey?: string; // Will be stored securely\n isEnabled: boolean;\n isDefault: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface AIModel {\n id: string;\n providerId: string;\n name: string;\n displayName: string;\n maxTokens: number;\n inputCostPer1k?: number;\n outputCostPer1k?: number;\n supportsStreaming: boolean;\n supportsTools: boolean;\n supportsVision: boolean;\n isEnabled: boolean;\n isDefault: boolean;\n}\n\n// Auto-routing configuration\nexport type TaskType = 'code_generation' | 'quick_answer' | 'file_analysis' | 'terminal_command' | 'code_review' | 'general';\n\nexport interface AutoRoutingRule {\n taskType: TaskType;\n preferredModelId: string;\n fallbackModelId?: string;\n}\n\nexport interface AISettings {\n providers: AIProvider[];\n models: AIModel[];\n autoRouting: {\n enabled: boolean;\n rules: AutoRoutingRule[];\n };\n advancedSettings: {\n temperature: number; // 0.0 - 2.0\n maxTokens: number; // Max response length\n conversationStyle: 'precise' | 'balanced' | 'creative';\n };\n defaultModelId: string | null;\n}\n\n// Chat message types\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n modelId?: string;\n toolCalls?: ToolCall[];\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n arguments: Record<string, unknown>;\n result?: unknown;\n status: 'pending' | 'approved' | 'rejected' | 'completed' | 'error';\n error?: string;\n}\n\n// Built-in provider presets\nexport const PROVIDER_PRESETS: Omit<AIProvider, 'id' | 'apiKey' | 'createdAt' | 'updatedAt'>[] = [\n {\n name: 'Google Gemini',\n type: 'google',\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenAI',\n type: 'openai',\n baseUrl: 'https://api.openai.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Anthropic',\n type: 'anthropic',\n baseUrl: 'https://api.anthropic.com/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'xAI (Grok)',\n type: 'xai',\n baseUrl: 'https://api.x.ai/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'OpenRouter',\n type: 'openrouter',\n baseUrl: 'https://openrouter.ai/api/v1',\n isEnabled: false,\n isDefault: false,\n },\n {\n name: 'Ollama (Local)',\n type: 'ollama',\n baseUrl: 'http://localhost:11434',\n isEnabled: false,\n isDefault: false,\n },\n];\n\n// Default models for each provider\nexport const DEFAULT_MODELS: Record<AIProviderType, Omit<AIModel, 'id' | 'providerId'>[]> = {\n google: [\n { name: 'gemini-2.5-flash-preview-05-20', displayName: 'Gemini 2.5 Flash', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'gemini-2.0-flash-exp', displayName: 'Gemini 2.0 Flash', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n { name: 'gemini-1.5-flash', displayName: 'Gemini 1.5 Flash', maxTokens: 32000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n openai: [\n { name: 'gpt-4o', displayName: 'GPT-4o', maxTokens: 128000, inputCostPer1k: 0.005, outputCostPer1k: 0.015, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'gpt-4o-mini', displayName: 'GPT-4o Mini', maxTokens: 128000, inputCostPer1k: 0.00015, outputCostPer1k: 0.0006, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n { name: 'gpt-4-turbo', displayName: 'GPT-4 Turbo', maxTokens: 128000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n anthropic: [\n { name: 'claude-3-5-sonnet-20241022', displayName: 'Claude 3.5 Sonnet', maxTokens: 200000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'claude-3-opus-20240229', displayName: 'Claude 3 Opus', maxTokens: 200000, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: false },\n ],\n xai: [\n { name: 'grok-beta', displayName: 'Grok Beta', maxTokens: 131072, supportsStreaming: true, supportsTools: true, supportsVision: false, isEnabled: true, isDefault: true },\n ],\n openrouter: [\n { name: 'google/gemini-2.0-flash-exp:free', displayName: 'Gemini 2.0 Flash (Free)', maxTokens: 8192, supportsStreaming: true, supportsTools: true, supportsVision: true, isEnabled: true, isDefault: true },\n { name: 'meta-llama/llama-3.2-3b-instruct:free', displayName: 'Llama 3.2 3B (Free)', maxTokens: 8192, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: false },\n ],\n ollama: [\n { name: 'llama3.2', displayName: 'Llama 3.2', maxTokens: 8192, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: true },\n { name: 'codellama', displayName: 'Code Llama', maxTokens: 4096, supportsStreaming: true, supportsTools: false, supportsVision: false, isEnabled: true, isDefault: false },\n ],\n custom: [],\n};\n\n// Helper to generate unique IDs\nexport const generateId = (): string => {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 9)}`;\n};\n\n// Initial empty settings\nexport const getDefaultAISettings = (): AISettings => ({\n providers: [],\n models: [],\n autoRouting: {\n enabled: false,\n rules: [],\n },\n advancedSettings: {\n temperature: 0.7,\n maxTokens: 4096,\n conversationStyle: 'balanced',\n },\n defaultModelId: null,\n});\n"}}}} |