Files

1 line
18 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "caokai1073/rivus", "files": {"config.py": {"c6978986e7c0bbc434b6d32e9dd5caad33d7bebd": {"t": 1785746632.2289705, "n": 5965, "h": "b96d7d18954efe4f", "c": "\"\"\"\nconfig.py — Application configuration persistence (API keys, etc.)\n\"\"\"\nAPP_VERSION = \"1.0.1\"\nUPDATE_CHECK_URL = \"https://api.github.com/repos/caokai1073/Rivus/releases/latest\"\n\nimport json\nimport os\nfrom pathlib import Path\n\n_data_dir = os.environ.get(\"MEMORYVAULT_DATA_DIR\")\nCONFIG_PATH = (\n Path(_data_dir) / \"config.json\" if _data_dir\n else Path(__file__).parent / \"config.json\"\n)\n\n# Cloud provider metadata\nCLOUD_PROVIDERS = {\n \"openai\": {\n \"name\": \"OpenAI / ChatGPT\",\n \"base_url\": \"https://api.openai.com/v1\",\n \"models\": [\n {\"id\": \"gpt-5.5\", \"label\": \"GPT-5.5 · Flagship\"},\n {\"id\": \"gpt-5.4\", \"label\": \"GPT-5.4\"},\n {\"id\": \"gpt-5.4-mini\", \"label\": \"GPT-5.4 mini\"},\n {\"id\": \"gpt-4.1\", \"label\": \"GPT-4.1\"},\n {\"id\": \"o3\", \"label\": \"o3 · Reasoning\"},\n ],\n },\n \"anthropic\": {\n \"name\": \"Anthropic / Claude\",\n \"base_url\": \"https://api.anthropic.com\",\n \"models\": [\n {\"id\": \"claude-fable-5\", \"label\": \"Claude Fable 5 · Flagship\"},\n {\"id\": \"claude-opus-4-8\", \"label\": \"Claude Opus 4.8\"},\n {\"id\": \"claude-sonnet-4-6\", \"label\": \"Claude Sonnet 4.6\"},\n {\"id\": \"claude-haiku-4-5-20251001\",\"label\": \"Claude Haiku 4.5\"},\n ],\n },\n \"qwen\": {\n \"name\": \"Qwen / 通义千问\",\n \"base_url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n \"models\": [\n {\"id\": \"qwen3-235b-a22b\", \"label\": \"Qwen3 235B · Flagship\"},\n {\"id\": \"qwen3-72b\", \"label\": \"Qwen3 72B\"},\n {\"id\": \"qwen-max\", \"label\": \"Qwen Max\"},\n {\"id\": \"qwen-plus\", \"label\": \"Qwen Plus\"},\n {\"id\": \"qwen-turbo\", \"label\": \"Qwen Turbo\"},\n ],\n },\n \"nvidia\": {\n \"name\": \"NVIDIA NIM\",\n \"base_url\": \"https://integrate.api.nvidia.com/v1\",\n \"models\": [\n {\"id\": \"nvidia/llama-3.1-nemotron-ultra-253b-v1\", \"label\": \"Nemotron Ultra 253B · Flagship\"},\n {\"id\": \"meta/llama-3.3-70b-instruct\", \"label\": \"Llama 3.3 70B\"},\n {\"id\": \"mistralai/mistral-large-2-instruct\", \"label\": \"Mistral Large 2\"},\n ],\n },\n \"deepseek\": {\n \"name\": \"DeepSeek\",\n \"base_url\": \"https://api.deepseek.com/v1\",\n \"models\": [\n {\"id\": \"deepseek-v4-flash\", \"label\": \"DeepSeek V4 Flash\"},\n {\"id\": \"deepseek-v4-pro\", \"label\": \"DeepSeek V4 Pro\"},\n ],\n },\n \"minimax\": {\n \"name\": \"MiniMax\",\n \"base_url\": \"https://api.minimax.chat/v1\",\n \"models\": [\n {\"id\": \"MiniMax-M1\", \"label\": \"MiniMax M1 · Flagship\"},\n {\"id\": \"MiniMax-Text-01\", \"label\": \"MiniMax Text-01\"},\n ],\n },\n \"glm\": {\n \"name\": \"GLM\",\n \"base_url\": \"https://open.bigmodel.cn/api/paas/v4\",\n \"models\": [\n {\"id\": \"glm-4-plus\", \"label\": \"GLM-4-Plus\"},\n {\"id\": \"glm-4-flash\", \"label\": \"GLM-4-Flash · Free\"},\n {\"id\": \"glm-z1-plus\", \"label\": \"GLM-Z1-Plus · Reasoning\"},\n ],\n },\n}\n\n\ndef load_config() -> dict:\n if CONFIG_PATH.exists():\n try:\n return json.loads(CONFIG_PATH.read_text(encoding=\"utf-8\"))\n except Exception:\n pass\n return {}\n\n\ndef save_config(config: dict):\n CONFIG_PATH.write_text(\n json.dumps(config, ensure_ascii=False, indent=2),\n encoding=\"utf-8\",\n )\n\n\nOLLAMA_OPTIONS_DEFAULTS = {\n \"num_ctx\": 8192, # context window (token count)\n \"temperature\": 0.8, # randomness (higher = more creative)\n \"top_p\": 0.9, # nucleus sampling\n \"repeat_penalty\": 1.1, # repetition penalty\n \"num_predict\": -1, # max output tokens (-1 = unlimited)\n}\n\n\ndef get_ollama_options() -> dict:\n return {**OLLAMA_OPTIONS_DEFAULTS,\n **load_config().get(\"ollama_options\", {})}\n\n\ndef set_ollama_options(options: dict):\n config = load_config()\n # Only save valid keys with basic type validation\n validated = {}\n for k, default in OLLAMA_OPTIONS_DEFAULTS.items():\n if k in options:\n try:\n validated[k] = type(default)(options[k])\n except (ValueError, TypeError):\n validated[k] = default\n config[\"ollama_options\"] = validated\n save_config(config)\n\n\ndef get_cloud_keys() -> dict:\n \"\"\"Returns {provider: {api_key, enabled}}\"\"\"\n return load_config().get(\"cloud_keys\", {})\n\n\ndef set_cloud_keys(keys: dict):\n config = load_config()\n config[\"cloud_keys\"] = keys\n save_config(config)\n\n\nREMOTE_SERVER_DEFAULTS = {\n \"host\": \"\",\n \"user\": \"\",\n \"ssh_port\": 22,\n \"auth_mode\": \"key\", # \"key\" | \"password\"\n \"key_path\": \"~/.ssh/id_rsa\",\n \"remote_port\": 11434,\n \"local_port\": 11435,\n}\n\n\ndef get_remote_config() -> dict:\n return {**REMOTE_SERVER_DEFAULTS,\n **load_config().get(\"remote_server\", {})}\n\n\ndef set_remote_config(cfg: dict):\n config = load_config()\n validated = {}\n for k, default in REMOTE_SERVER_DEFAULTS.items():\n if k in cfg:\n try:\n validated[k] = type(default)(cfg[k])\n except (ValueError, TypeError):\n validated[k] = default\n config[\"remote_server\"] = validated\n save_config(config)\n\n\ndef get_enabled_cloud_models() -> list[dict]:\n \"\"\"Returns list of cloud models with configured API keys, same format as Ollama models\"\"\"\n keys = get_cloud_keys()\n models = []\n for provider, meta in CLOUD_PROVIDERS.items():\n entry = keys.get(provider, {})\n if entry.get(\"api_key\") and entry.get(\"enabled\", True):\n for m in meta[\"models\"]:\n models.append({\n \"id\": f\"cloud:{provider}:{m['id']}\",\n \"label\": f\"☁️ {m['label']}\",\n \"provider\": provider,\n })\n return models\n"}, "a5dc9bc9b764c87348c58368f918e234663b8e6d": {"t": 1785766413.9012713, "n": 5965, "h": "b96d7d18954efe4f", "c": "\"\"\"\nconfig.py — Application configuration persistence (API keys, etc.)\n\"\"\"\nAPP_VERSION = \"1.0.1\"\nUPDATE_CHECK_URL = \"https://api.github.com/repos/caokai1073/Rivus/releases/latest\"\n\nimport json\nimport os\nfrom pathlib import Path\n\n_data_dir = os.environ.get(\"MEMORYVAULT_DATA_DIR\")\nCONFIG_PATH = (\n Path(_data_dir) / \"config.json\" if _data_dir\n else Path(__file__).parent / \"config.json\"\n)\n\n# Cloud provider metadata\nCLOUD_PROVIDERS = {\n \"openai\": {\n \"name\": \"OpenAI / ChatGPT\",\n \"base_url\": \"https://api.openai.com/v1\",\n \"models\": [\n {\"id\": \"gpt-5.5\", \"label\": \"GPT-5.5 · Flagship\"},\n {\"id\": \"gpt-5.4\", \"label\": \"GPT-5.4\"},\n {\"id\": \"gpt-5.4-mini\", \"label\": \"GPT-5.4 mini\"},\n {\"id\": \"gpt-4.1\", \"label\": \"GPT-4.1\"},\n {\"id\": \"o3\", \"label\": \"o3 · Reasoning\"},\n ],\n },\n \"anthropic\": {\n \"name\": \"Anthropic / Claude\",\n \"base_url\": \"https://api.anthropic.com\",\n \"models\": [\n {\"id\": \"claude-fable-5\", \"label\": \"Claude Fable 5 · Flagship\"},\n {\"id\": \"claude-opus-4-8\", \"label\": \"Claude Opus 4.8\"},\n {\"id\": \"claude-sonnet-4-6\", \"label\": \"Claude Sonnet 4.6\"},\n {\"id\": \"claude-haiku-4-5-20251001\",\"label\": \"Claude Haiku 4.5\"},\n ],\n },\n \"qwen\": {\n \"name\": \"Qwen / 通义千问\",\n \"base_url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n \"models\": [\n {\"id\": \"qwen3-235b-a22b\", \"label\": \"Qwen3 235B · Flagship\"},\n {\"id\": \"qwen3-72b\", \"label\": \"Qwen3 72B\"},\n {\"id\": \"qwen-max\", \"label\": \"Qwen Max\"},\n {\"id\": \"qwen-plus\", \"label\": \"Qwen Plus\"},\n {\"id\": \"qwen-turbo\", \"label\": \"Qwen Turbo\"},\n ],\n },\n \"nvidia\": {\n \"name\": \"NVIDIA NIM\",\n \"base_url\": \"https://integrate.api.nvidia.com/v1\",\n \"models\": [\n {\"id\": \"nvidia/llama-3.1-nemotron-ultra-253b-v1\", \"label\": \"Nemotron Ultra 253B · Flagship\"},\n {\"id\": \"meta/llama-3.3-70b-instruct\", \"label\": \"Llama 3.3 70B\"},\n {\"id\": \"mistralai/mistral-large-2-instruct\", \"label\": \"Mistral Large 2\"},\n ],\n },\n \"deepseek\": {\n \"name\": \"DeepSeek\",\n \"base_url\": \"https://api.deepseek.com/v1\",\n \"models\": [\n {\"id\": \"deepseek-v4-flash\", \"label\": \"DeepSeek V4 Flash\"},\n {\"id\": \"deepseek-v4-pro\", \"label\": \"DeepSeek V4 Pro\"},\n ],\n },\n \"minimax\": {\n \"name\": \"MiniMax\",\n \"base_url\": \"https://api.minimax.chat/v1\",\n \"models\": [\n {\"id\": \"MiniMax-M1\", \"label\": \"MiniMax M1 · Flagship\"},\n {\"id\": \"MiniMax-Text-01\", \"label\": \"MiniMax Text-01\"},\n ],\n },\n \"glm\": {\n \"name\": \"GLM\",\n \"base_url\": \"https://open.bigmodel.cn/api/paas/v4\",\n \"models\": [\n {\"id\": \"glm-4-plus\", \"label\": \"GLM-4-Plus\"},\n {\"id\": \"glm-4-flash\", \"label\": \"GLM-4-Flash · Free\"},\n {\"id\": \"glm-z1-plus\", \"label\": \"GLM-Z1-Plus · Reasoning\"},\n ],\n },\n}\n\n\ndef load_config() -> dict:\n if CONFIG_PATH.exists():\n try:\n return json.loads(CONFIG_PATH.read_text(encoding=\"utf-8\"))\n except Exception:\n pass\n return {}\n\n\ndef save_config(config: dict):\n CONFIG_PATH.write_text(\n json.dumps(config, ensure_ascii=False, indent=2),\n encoding=\"utf-8\",\n )\n\n\nOLLAMA_OPTIONS_DEFAULTS = {\n \"num_ctx\": 8192, # context window (token count)\n \"temperature\": 0.8, # randomness (higher = more creative)\n \"top_p\": 0.9, # nucleus sampling\n \"repeat_penalty\": 1.1, # repetition penalty\n \"num_predict\": -1, # max output tokens (-1 = unlimited)\n}\n\n\ndef get_ollama_options() -> dict:\n return {**OLLAMA_OPTIONS_DEFAULTS,\n **load_config().get(\"ollama_options\", {})}\n\n\ndef set_ollama_options(options: dict):\n config = load_config()\n # Only save valid keys with basic type validation\n validated = {}\n for k, default in OLLAMA_OPTIONS_DEFAULTS.items():\n if k in options:\n try:\n validated[k] = type(default)(options[k])\n except (ValueError, TypeError):\n validated[k] = default\n config[\"ollama_options\"] = validated\n save_config(config)\n\n\ndef get_cloud_keys() -> dict:\n \"\"\"Returns {provider: {api_key, enabled}}\"\"\"\n return load_config().get(\"cloud_keys\", {})\n\n\ndef set_cloud_keys(keys: dict):\n config = load_config()\n config[\"cloud_keys\"] = keys\n save_config(config)\n\n\nREMOTE_SERVER_DEFAULTS = {\n \"host\": \"\",\n \"user\": \"\",\n \"ssh_port\": 22,\n \"auth_mode\": \"key\", # \"key\" | \"password\"\n \"key_path\": \"~/.ssh/id_rsa\",\n \"remote_port\": 11434,\n \"local_port\": 11435,\n}\n\n\ndef get_remote_config() -> dict:\n return {**REMOTE_SERVER_DEFAULTS,\n **load_config().get(\"remote_server\", {})}\n\n\ndef set_remote_config(cfg: dict):\n config = load_config()\n validated = {}\n for k, default in REMOTE_SERVER_DEFAULTS.items():\n if k in cfg:\n try:\n validated[k] = type(default)(cfg[k])\n except (ValueError, TypeError):\n validated[k] = default\n config[\"remote_server\"] = validated\n save_config(config)\n\n\ndef get_enabled_cloud_models() -> list[dict]:\n \"\"\"Returns list of cloud models with configured API keys, same format as Ollama models\"\"\"\n keys = get_cloud_keys()\n models = []\n for provider, meta in CLOUD_PROVIDERS.items():\n entry = keys.get(provider, {})\n if entry.get(\"api_key\") and entry.get(\"enabled\", True):\n for m in meta[\"models\"]:\n models.append({\n \"id\": f\"cloud:{provider}:{m['id']}\",\n \"label\": f\"☁️ {m['label']}\",\n \"provider\": provider,\n })\n return models\n"}, "05e33f03f624b1d6fa6af95685996771002ad29f": {"t": 1785766415.3497667, "n": 4168, "h": "1511abbaa1d55414", "c": "\"\"\"\nconfig.py — 应用配置持久化(API 密钥等)\n\"\"\"\nAPP_VERSION = \"1.0.0\"\n# 填入 GitHub releases API URL 后即可启用自动更新检测\n# 例: \"https://api.github.com/repos/yourname/rivus/releases/latest\"\nUPDATE_CHECK_URL = \"\"\n\nimport json\nimport os\nfrom pathlib import Path\n\n_data_dir = os.environ.get(\"MEMORYVAULT_DATA_DIR\")\nCONFIG_PATH = (\n Path(_data_dir) / \"config.json\" if _data_dir\n else Path(__file__).parent / \"config.json\"\n)\n\n# 云端提供商元数据\nCLOUD_PROVIDERS = {\n \"deepseek\": {\n \"name\": \"DeepSeek\",\n \"base_url\": \"https://api.deepseek.com/v1\",\n \"models\": [\n {\"id\": \"deepseek-v4-flash\", \"label\": \"DeepSeek V4 Flash\"},\n {\"id\": \"deepseek-v4-pro\", \"label\": \"DeepSeek V4 Pro\"},\n ],\n },\n \"openai\": {\n \"name\": \"OpenAI / ChatGPT\",\n \"base_url\": \"https://api.openai.com/v1\",\n \"models\": [\n {\"id\": \"gpt-5.5\", \"label\": \"GPT-5.5 · Flagship\"},\n {\"id\": \"gpt-5.4\", \"label\": \"GPT-5.4\"},\n {\"id\": \"gpt-5.4-mini\", \"label\": \"GPT-5.4 mini\"},\n {\"id\": \"gpt-4.1\", \"label\": \"GPT-4.1\"},\n {\"id\": \"o3\", \"label\": \"o3 · Reasoning\"},\n ],\n },\n \"anthropic\": {\n \"name\": \"Anthropic / Claude\",\n \"base_url\": \"https://api.anthropic.com\",\n \"models\": [\n {\"id\": \"claude-fable-5\", \"label\": \"Claude Fable 5 · Flagship\"},\n {\"id\": \"claude-opus-4-8\", \"label\": \"Claude Opus 4.8\"},\n {\"id\": \"claude-sonnet-4-6\", \"label\": \"Claude Sonnet 4.6\"},\n {\"id\": \"claude-haiku-4-5-20251001\",\"label\": \"Claude Haiku 4.5\"},\n ],\n },\n \"minimax\": {\n \"name\": \"MiniMax\",\n \"base_url\": \"https://api.minimax.chat/v1\",\n \"models\": [\n {\"id\": \"MiniMax-M1\", \"label\": \"MiniMax M1 · Flagship\"},\n {\"id\": \"MiniMax-Text-01\", \"label\": \"MiniMax Text-01\"},\n ],\n },\n \"glm\": {\n \"name\": \"智谱 GLM\",\n \"base_url\": \"https://open.bigmodel.cn/api/paas/v4\",\n \"models\": [\n {\"id\": \"glm-4-plus\", \"label\": \"GLM-4-Plus\"},\n {\"id\": \"glm-4-flash\", \"label\": \"GLM-4-Flash · Free\"},\n {\"id\": \"glm-z1-plus\", \"label\": \"GLM-Z1-Plus · Reasoning\"},\n ],\n },\n}\n\n\ndef load_config() -> dict:\n if CONFIG_PATH.exists():\n try:\n return json.loads(CONFIG_PATH.read_text(encoding=\"utf-8\"))\n except Exception:\n pass\n return {}\n\n\ndef save_config(config: dict):\n CONFIG_PATH.write_text(\n json.dumps(config, ensure_ascii=False, indent=2),\n encoding=\"utf-8\",\n )\n\n\nOLLAMA_OPTIONS_DEFAULTS = {\n \"num_ctx\": 4096, # 上下文窗口(token 数)\n \"temperature\": 0.8, # 随机性(越高越有创意)\n \"top_p\": 0.9, # nucleus sampling\n \"repeat_penalty\": 1.1, # 重复惩罚\n \"num_predict\": -1, # 最大输出 token(-1 = 不限)\n}\n\n\ndef get_ollama_options() -> dict:\n return {**OLLAMA_OPTIONS_DEFAULTS,\n **load_config().get(\"ollama_options\", {})}\n\n\ndef set_ollama_options(options: dict):\n config = load_config()\n # 只保存有效键,值做基本类型校验\n validated = {}\n for k, default in OLLAMA_OPTIONS_DEFAULTS.items():\n if k in options:\n try:\n validated[k] = type(default)(options[k])\n except (ValueError, TypeError):\n validated[k] = default\n config[\"ollama_options\"] = validated\n save_config(config)\n\n\ndef get_cloud_keys() -> dict:\n \"\"\"返回 {provider: {api_key, enabled}} \"\"\"\n return load_config().get(\"cloud_keys\", {})\n\n\ndef set_cloud_keys(keys: dict):\n config = load_config()\n config[\"cloud_keys\"] = keys\n save_config(config)\n\n\ndef get_enabled_cloud_models() -> list[dict]:\n \"\"\"返回已配置 API Key 的云端模型列表,格式同 Ollama models\"\"\"\n keys = get_cloud_keys()\n models = []\n for provider, meta in CLOUD_PROVIDERS.items():\n entry = keys.get(provider, {})\n if entry.get(\"api_key\") and entry.get(\"enabled\", True):\n for m in meta[\"models\"]:\n models.append({\n \"id\": f\"cloud:{provider}:{m['id']}\",\n \"label\": f\"☁️ {m['label']}\",\n \"provider\": provider,\n })\n return models\n"}}}}