Files

1 line
5.7 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": "bcefghj/xiaonian", "files": {".env.example": {"a57dfbac7e0b119cfefac3970afb04be25df7b8a": {"t": 1785604107.7277687, "n": 991, "h": "ce89d7115ff04fcc", "c": "# 小念 XiaoNian — 环境配置示例\n# 复制为 .env 后填入你的密钥。所有数据与密钥仅保存在本机。\n\n# ===== 默认使用的模型 provider:minimax | deepseek | mimo | mock =====\nXIAONIAN_PROVIDER=minimax\n\n# ===== MiniMax(主力)=====\n# coding 套餐 key(sk-cp-...)走 Anthropic 兼容端点(与 OpenAI 文本接口是不同额度池)\nMINIMAX_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx\nMINIMAX_BASE_URL=https://api.minimaxi.com/anthropic\nMINIMAX_PROTOCOL=anthropic\nMINIMAX_MODEL=MiniMax-M2\n\n# ===== DeepSeek(高性价比备选)=====\nDEEPSEEK_API_KEY=\nDEEPSEEK_BASE_URL=https://api.deepseek.com/v1\nDEEPSEEK_MODEL=deepseek-chat\n\n# ===== 小米 MiMo(生态加分,OpenAI 兼容)=====\nMIMO_API_KEY=\nMIMO_BASE_URL=https://api.example-mimo.xiaomi.com/v1\nMIMO_MODEL=mimo\n\n# ===== 服务 =====\nXIAONIAN_HOST=127.0.0.1\nXIAONIAN_PORT=8765\n\n# ===== 安全/隐私 =====\n# 写操作(删除/移动/执行命令/下单)是否需要两步确认\nXIAONIAN_REQUIRE_CONFIRM=true\n# 上云前 PII 脱敏\nXIAONIAN_REDACT_PII=true\n\n# ===== 主动关心引擎 =====\nXIAONIAN_PROACTIVE_ENABLED=true\n# 静默时段(不主动打扰),24h\nXIAONIAN_QUIET_START=23\nXIAONIAN_QUIET_END=8\n\n# ===== 用户 =====\nXIAONIAN_USER_ID=master\nXIAONIAN_USER_NAME=主人\n"}}, "config.py": {"9813677eed179f6341028448837ecb297a2f5ab7": {"t": 1785604109.1580005, "n": 3027, "h": "b4cebea76b223276", "c": "\"\"\"小念 XiaoNian — 全局配置。\n\n集中读取环境变量(.env),供各层使用。所有路径默认指向本机 data/ 目录,\n体现\"数据全本地\"的隐私原则。\n\"\"\"\nfrom __future__ import annotations\n\nimport os\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Dict\n\ntry:\n from dotenv import load_dotenv\n\n load_dotenv()\nexcept Exception: # pragma: no cover - dotenv 可选\n pass\n\n\nROOT = Path(__file__).resolve().parent\nDATA_DIR = ROOT / \"data\"\nDATA_DIR.mkdir(exist_ok=True)\n\n\ndef _b(key: str, default: bool) -> bool:\n v = os.getenv(key)\n if v is None:\n return default\n return v.strip().lower() in {\"1\", \"true\", \"yes\", \"on\"}\n\n\n@dataclass\nclass ProviderConfig:\n \"\"\"单个模型 provider 的连接配置。\n\n protocol:openai(OpenAI 兼容 /chat/completions)或 anthropic(Anthropic 兼容\n /v1/messages)。MiniMax 的 coding 套餐 key 走 anthropic 协议(与 OpenAI 文本\n 接口是不同的额度池)。\n \"\"\"\n\n name: str\n api_key: str\n base_url: str\n model: str\n protocol: str = \"openai\"\n\n @property\n def available(self) -> bool:\n return bool(self.api_key) and not self.api_key.startswith(\"sk-xxxx\")\n\n\n@dataclass\nclass Settings:\n user_id: str = os.getenv(\"XIAONIAN_USER_ID\", \"master\")\n user_name: str = os.getenv(\"XIAONIAN_USER_NAME\", \"主人\")\n host: str = os.getenv(\"XIAONIAN_HOST\", \"127.0.0.1\")\n port: int = int(os.getenv(\"XIAONIAN_PORT\", \"8765\"))\n\n default_provider: str = os.getenv(\"XIAONIAN_PROVIDER\", \"minimax\")\n\n require_confirm: bool = _b(\"XIAONIAN_REQUIRE_CONFIRM\", True)\n redact_pii: bool = _b(\"XIAONIAN_REDACT_PII\", True)\n\n proactive_enabled: bool = _b(\"XIAONIAN_PROACTIVE_ENABLED\", True)\n quiet_start: int = int(os.getenv(\"XIAONIAN_QUIET_START\", \"23\"))\n quiet_end: int = int(os.getenv(\"XIAONIAN_QUIET_END\", \"8\"))\n\n providers: Dict[str, ProviderConfig] = field(default_factory=dict)\n\n def __post_init__(self) -> None:\n self.providers = {\n \"minimax\": ProviderConfig(\n name=\"minimax\",\n api_key=os.getenv(\"MINIMAX_API_KEY\", \"\"),\n base_url=os.getenv(\"MINIMAX_BASE_URL\", \"https://api.minimaxi.com/anthropic\"),\n model=os.getenv(\"MINIMAX_MODEL\", \"MiniMax-M2\"),\n protocol=os.getenv(\"MINIMAX_PROTOCOL\", \"anthropic\"),\n ),\n \"deepseek\": ProviderConfig(\n name=\"deepseek\",\n api_key=os.getenv(\"DEEPSEEK_API_KEY\", \"\"),\n base_url=os.getenv(\"DEEPSEEK_BASE_URL\", \"https://api.deepseek.com/v1\"),\n model=os.getenv(\"DEEPSEEK_MODEL\", \"deepseek-chat\"),\n ),\n \"mimo\": ProviderConfig(\n name=\"mimo\",\n api_key=os.getenv(\"MIMO_API_KEY\", \"\"),\n base_url=os.getenv(\"MIMO_BASE_URL\", \"\"),\n model=os.getenv(\"MIMO_MODEL\", \"mimo\"),\n ),\n }\n\n def provider(self, name: str | None = None) -> ProviderConfig:\n return self.providers.get(name or self.default_provider, self.providers[\"minimax\"])\n\n @property\n def data_dir(self) -> Path:\n return DATA_DIR\n\n\nsettings = Settings()\n"}}, "run.py": {"dd652ac22163bac6e81b92bcaf2519b970aee9cd": {"t": 1785604110.3626041, "n": 518, "h": "9f1902d43cec6842", "c": "\"\"\"小念 XiaoNian 启动入口。\n\n用法:\n python run.py\n然后浏览器打开 http://127.0.0.1:8765\n\"\"\"\nfrom __future__ import annotations\n\nimport uvicorn\n\nfrom config import settings\n\nif __name__ == \"__main__\":\n print(\"=\" * 56)\n print(\" 小念 XiaoNian — 你电脑里会成长的生活助理\")\n print(f\" 本地服务: http://{settings.host}:{settings.port}\")\n print(f\" 默认模型: {settings.default_provider}\")\n print(f\" 数据目录: {settings.data_dir}(全部留在本机)\")\n print(\"=\" * 56)\n uvicorn.run(\"daemon.main:app\", host=settings.host, port=settings.port, reload=False)\n"}}}}