// @ts-nocheck export const CONFIG = { ZHONGTAI_BASE: 'http://127.0.0.1:8088', ZHONGTAI_METRICS_PATH: '/metrics', ZHONGTAI_PROXY_PATH: '/proxy/anthropic-messages', ZHONGTAI_OMLX_PROXY_PATH: '/proxy/omlx-chat', MCP_BASE: 'http://127.0.0.1:7777', MCP_PATH: '/mcp', HTTP_PATH_PREFIX: '/api/', OMLX_BASE: 'http://127.0.0.1:8000', OMLX_CHAT_PATH: '/v1/chat/completions', SPARKLE_BASE: 'http://127.0.0.1:8317', SPARKLE_CHAT_PATH: '/v1/chat/completions', MAX_TURNS: 8, MAX_SAME_ERROR: 4, MAX_REPORT_ROUNDS: 10, REPORT_MAX_TOKENS: 1800, METRICS_POLL_MS: 1500, STREAM_RAF: true, TOKEN_STORAGE_KEY: 'ccsparkle_agent_token', MODE_STORAGE_KEY: 'ccsparkle_agent_mode', MODEL_SOURCE_KEY: 'ccsparkle_model_source', DEFAULT_SOURCE_KEY: 'ccsparkle_default_source', OLLAMA_CFG_KEY: 'ccsparkle_ollama_cfg', ANTHROPIC_CFG_KEY: 'ccsparkle_anthropic_cfg', OMLX_CFG_KEY: 'ccsparkle_omlx_cfg', SPARKLE_CFG_KEY: 'ccsparkle_sparkle_cfg', HISTORY_STORAGE_KEY: 'ccsparkle_history', CONTEXT_THRESHOLD_KEY: 'ccsparkle_context_threshold', THINKING_ENABLED_KEY: 'ccsparkle_thinking_enabled', CROSS_MODULE_ENABLED_KEY: 'ccsparkle_cross_module_enabled', }; export function zhongtaiMetricsUrl() { return `${CONFIG.ZHONGTAI_BASE}${CONFIG.ZHONGTAI_METRICS_PATH}`; } export function zhongtaiProxyUrl() { return `${CONFIG.ZHONGTAI_BASE}${CONFIG.ZHONGTAI_PROXY_PATH}`; } export function zhongtaiOmlxProxyUrl() { return `${CONFIG.ZHONGTAI_BASE}${CONFIG.ZHONGTAI_OMLX_PROXY_PATH}`; } export const DEFAULT_OLLAMA = { baseUrl: 'http://127.0.0.1:11434', model: '', }; export const DEFAULT_ANTHROPIC = { baseUrl: '', authToken: '', protocol: 'anthropic', preset: 'custom', fastModel: '', standardModel: '', proModel: '', currentTier: 'fast', apiVersion: '2023-06-01', maxTokens: 4096, presets: {}, }; export const CLOUD_API_PRESETS = [ { id: 'zhipu_coding_anthropic', label: '智谱 Coding · Messages', protocol: 'anthropic', baseUrl: 'https://open.bigmodel.cn/api/anthropic', hint: '智谱 Coding Plan 套餐额度,Messages API', }, { id: 'zhipu_coding_openai', label: '智谱 Coding · Chat', protocol: 'openai', baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4', hint: '智谱 Coding Plan 套餐额度,Chat Completions', }, { id: 'zhipu_balance', label: '智谱 · 账号余额', protocol: 'openai', baseUrl: 'https://open.bigmodel.cn/api/paas/v4', hint: '智谱独立计费,不消耗套餐', }, { id: 'bailian_anthropic', label: '百炼 · Anthropic', protocol: 'anthropic', baseUrl: 'https://dashscope.aliyuncs.com/apps/anthropic', hint: '阿里云百炼(北京),Messages API;Token 填 DashScope API Key', models: { fastModel: 'qwen-flash', standardModel: 'qwen3.7-plus', proModel: 'qwen3.7-max', currentTier: 'pro', }, }, { id: 'bailian_openai', label: '百炼 · OpenAI', protocol: 'openai', baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1', hint: '阿里云百炼(北京),Chat Completions;Token 填 DashScope API Key', models: { fastModel: 'qwen-flash', standardModel: 'qwen3.7-plus', proModel: 'qwen3.7-max', currentTier: 'pro', }, }, { id: 'deepseek_official', label: 'DeepSeek · 官方', protocol: 'openai', baseUrl: 'https://api.deepseek.com/v1', hint: 'DeepSeek 官方,OpenAI 兼容;Token 填 DeepSeek API Key', models: { fastModel: 'deepseek-v4-flash', standardModel: '', proModel: 'deepseek-v4-pro', currentTier: 'pro', }, }, { id: 'moonshot_official', label: 'Moonshot Kimi · 官方按量', protocol: 'openai', baseUrl: 'https://api.moonshot.cn/v1', hint: 'Moonshot 官方按量计费,OpenAI 兼容;Token 填 Moonshot API Key', models: { fastModel: 'moonshot-v1-8k', standardModel: 'moonshot-v1-32k', proModel: 'moonshot-v1-128k', currentTier: 'pro', }, }, { id: 'kimi_coding_plan', label: 'Kimi Code Plan · 套餐', protocol: 'openai', baseUrl: 'https://api.kimi.com/coding/v1', hint: 'Kimi Code Plan 套餐(Andante/Moderato/Allegretto/Allegro),OpenAI 兼容;Token 填 Kimi 平台 API Key', models: { fastModel: 'kimi-k3', standardModel: 'kimi-k3', proModel: 'kimi-k3', currentTier: 'pro', }, }, { id: 'qianfan_openai', label: '百度千帆 · OpenAI', protocol: 'openai', baseUrl: 'https://qianfan.baidubce.com/v2/compatible', hint: '百度千帆(OpenAI 兼容模式);Token 塺千帆 API Key(用 Bearer 鉴权)', models: { fastModel: 'ernie-speed-8k', standardModel: 'ernie-4.0-8k-latest', proModel: 'ernie-4.5-8k-latest', currentTier: 'pro', }, }, { id: 'custom', label: '自定义', protocol: null, baseUrl: null, hint: '自行填写 Base URL 与协议', }, ]; export const DEFAULT_OMLX = { baseUrl: 'http://127.0.0.1:8000', apiKey: '', model: '', }; export const DEFAULT_SPARKLE = { baseUrl: 'http://127.0.0.1:8317', apiKey: '', model: '', }; export function mcpUrl() { return `${CONFIG.MCP_BASE}${CONFIG.MCP_PATH}`; } export function httpUrl(toolName) { return `${CONFIG.MCP_BASE}${CONFIG.HTTP_PATH_PREFIX}${toolName}`; } export function loadToken() { const params = new URLSearchParams(location.search); const fromUrl = params.get('token'); if (fromUrl) { localStorage.setItem(CONFIG.TOKEN_STORAGE_KEY, fromUrl); return fromUrl; } const stored = localStorage.getItem(CONFIG.TOKEN_STORAGE_KEY); if (stored) return stored; return ''; } export function loadMode() { return localStorage.getItem(CONFIG.MODE_STORAGE_KEY) || 'mcp'; } export function saveMode(mode) { localStorage.setItem(CONFIG.MODE_STORAGE_KEY, mode); } export function loadModelSource() { const last = localStorage.getItem(CONFIG.MODEL_SOURCE_KEY); if (last) return last; return localStorage.getItem(CONFIG.DEFAULT_SOURCE_KEY) || 'ollama'; } export function saveModelSource(source) { localStorage.setItem(CONFIG.MODEL_SOURCE_KEY, source); } export function loadDefaultSource() { return localStorage.getItem(CONFIG.DEFAULT_SOURCE_KEY) || 'ollama'; } export function saveDefaultSource(source) { localStorage.setItem(CONFIG.DEFAULT_SOURCE_KEY, source); localStorage.setItem(CONFIG.MODEL_SOURCE_KEY, source); } export function loadOllamaConfig() { try { const s = localStorage.getItem(CONFIG.OLLAMA_CFG_KEY); if (s) { const cfg = { ...DEFAULT_OLLAMA, ...JSON.parse(s) }; if (!String(cfg.baseUrl || '').trim()) cfg.baseUrl = DEFAULT_OLLAMA.baseUrl; return cfg; } } catch (e) {} return { ...DEFAULT_OLLAMA }; } export function saveOllamaConfig(cfg) { localStorage.setItem(CONFIG.OLLAMA_CFG_KEY, JSON.stringify(cfg)); } export function loadAnthropicConfig() { try { const s = localStorage.getItem(CONFIG.ANTHROPIC_CFG_KEY); if (s) { const raw = JSON.parse(s); const cfg = { ...DEFAULT_ANTHROPIC, ...raw }; if (raw.protocol == null) { const base = (cfg.baseUrl || '').toLowerCase(); if (/\/paas\/v4|\/coding\/paas/.test(base)) { cfg.protocol = 'openai'; } } return cfg; } } catch (e) {} return { ...DEFAULT_ANTHROPIC }; } export function saveAnthropicConfig(cfg) { localStorage.setItem(CONFIG.ANTHROPIC_CFG_KEY, JSON.stringify(cfg)); } export function loadOmlxConfig() { try { const s = localStorage.getItem(CONFIG.OMLX_CFG_KEY); if (s) { const cfg = { ...DEFAULT_OMLX, ...JSON.parse(s) }; if (!String(cfg.baseUrl || '').trim()) cfg.baseUrl = DEFAULT_OMLX.baseUrl; return cfg; } } catch (e) {} return { ...DEFAULT_OMLX }; } export function saveOmlxConfig(cfg) { localStorage.setItem(CONFIG.OMLX_CFG_KEY, JSON.stringify(cfg)); } export function loadSparkleConfig() { try { const s = localStorage.getItem(CONFIG.SPARKLE_CFG_KEY); if (s) { const cfg = { ...DEFAULT_SPARKLE, ...JSON.parse(s) }; if (!String(cfg.baseUrl || '').trim()) cfg.baseUrl = DEFAULT_SPARKLE.baseUrl; return cfg; } } catch (e) {} return { ...DEFAULT_SPARKLE }; } export function saveSparkleConfig(cfg) { localStorage.setItem(CONFIG.SPARKLE_CFG_KEY, JSON.stringify(cfg)); } export function loadHistory() { try { const s = localStorage.getItem(CONFIG.HISTORY_STORAGE_KEY); return s ? JSON.parse(s) : []; } catch (e) { return []; } } export function saveHistory(history) { try { const slim = history .filter(m => m.role === 'user' || m.role === 'assistant') .map(m => ({ role: m.role, content: typeof m.content === 'string' ? m.content.slice(0, 4000) : '', thinking: typeof m.thinking === 'string' && m.thinking ? m.thinking.slice(0, 8000) : undefined, })); localStorage.setItem(CONFIG.HISTORY_STORAGE_KEY, JSON.stringify(slim)); } catch (e) {} } export function clearHistoryStorage() { localStorage.removeItem(CONFIG.HISTORY_STORAGE_KEY); } export function loadThinkingEnabled() { return localStorage.getItem(CONFIG.THINKING_ENABLED_KEY) === '1'; } export function saveThinkingEnabled(on) { localStorage.setItem(CONFIG.THINKING_ENABLED_KEY, on ? '1' : '0'); } export function loadCrossModuleEnabled() { return localStorage.getItem(CONFIG.CROSS_MODULE_ENABLED_KEY) === '1'; } export function saveCrossModuleEnabled(on) { localStorage.setItem(CONFIG.CROSS_MODULE_ENABLED_KEY, on ? '1' : '0'); } export function modelThinkingCapability(modelName) { const m = String(modelName || ''); if (!m) return 'unknown'; const lower = m.toLowerCase(); if (/instruct-2507/i.test(m) && !/thinking/i.test(m)) return 'no'; if (/thinking-2507/i.test(m) || /[/_\-]thinking([/_\-]|$)/i.test(lower)) return 'yes'; if (/qwen3(\.|\d|$)/i.test(m) && !/instruct-2507/i.test(m)) return 'yes'; if (/glm-?(4\.5|4\.6|4\.7|5)/i.test(m) || /deepseek.*reasoner|deepseek-r1|deepseek-v[34]/i.test(lower)) return 'yes'; if (/claude.*(opus|sonnet|4)/i.test(lower)) return 'yes'; if (/qwen2\.5/i.test(m)) return 'no'; return 'unknown'; } export const THRESHOLD_OPTIONS = [ { value: 8000, label: '紧凑(8k)— 小 context 模型' }, { value: 24000, label: '标准(24k)— 32k 模型' }, { value: 48000, label: '宽松(48k)— 64k+ 模型' }, { value: 96000, label: '超大(96k)— 128k 模型' }, { value: 500000, label: '极限(500k)— 长上下文模型' }, { value: 9999999, label: '关闭(不压缩)' }, ]; const DEFAULT_THRESHOLD_BY_SOURCE = { ollama: 24000, omlx: 24000, sparkle: 24000, anthropic: 96000, }; export function loadContextThreshold(source) { const key = `${CONFIG.CONTEXT_THRESHOLD_KEY}_${source || 'ollama'}`; const v = parseInt(localStorage.getItem(key), 10); if (v > 0) return v; return DEFAULT_THRESHOLD_BY_SOURCE[source] || 24000; } export function saveContextThreshold(source, v) { const key = `${CONFIG.CONTEXT_THRESHOLD_KEY}_${source}`; localStorage.setItem(key, String(v)); } export function getCurrentModelInfo() { const source = loadModelSource(); if (source === 'anthropic') { const cfg = loadAnthropicConfig(); const tierModel = ({ fast: cfg.fastModel, standard: cfg.standardModel, pro: cfg.proModel, })[cfg.currentTier] || cfg.fastModel; const tierLabel = ({ fast: '快速档', standard: '平衡档', pro: '增强档', })[cfg.currentTier] || ''; return { source, sourceLabel: '云端', model: tierModel, tier: cfg.currentTier, tierLabel, protocol: cfg.protocol === 'openai' ? 'openai' : 'anthropic', isLocal: false, }; } if (source === 'omlx') { const cfg = loadOmlxConfig(); return { source, sourceLabel: '本地', model: cfg.model, isLocal: true, }; } if (source === 'sparkle') { const cfg = loadSparkleConfig(); return { source, sourceLabel: '本地', model: cfg.model, isLocal: true, }; } const cfg = loadOllamaConfig(); return { source, sourceLabel: '本地', model: cfg.model, isLocal: true, }; } export function ollamaUrl() { const cfg = loadOllamaConfig(); const base = String(cfg.baseUrl || DEFAULT_OLLAMA.baseUrl).replace(/\/+$/, ''); return `${base}/api/chat`; } export function anthropicUrl() { const cfg = loadAnthropicConfig(); const base = (cfg.baseUrl || '').replace(/\/+$/, ''); if ((cfg.protocol || 'anthropic') === 'openai') { return `${base}/chat/completions`; } return `${base}/v1/messages`; } export function cloudProtocol() { const cfg = loadAnthropicConfig(); return cfg.protocol === 'openai' ? 'openai' : 'anthropic'; } export function omlxUrl() { const cfg = loadOmlxConfig(); const base = String(cfg.baseUrl || DEFAULT_OMLX.baseUrl).replace(/\/+$/, ''); return `${base}${CONFIG.OMLX_CHAT_PATH}`; } export function sparkleUrl() { const cfg = loadSparkleConfig(); const base = String(cfg.baseUrl || DEFAULT_SPARKLE.baseUrl).replace(/\/+$/, ''); return `${base}${CONFIG.SPARKLE_CHAT_PATH}`; }