1 line
7.1 KiB
JSON
1 line
7.1 KiB
JSON
{"repo": "chengguanglab/wechat-", "files": {"settings.py": {"c075ad81c6131c2cbc9ee3b571fea0bc6f92370e": {"t": 1785674171.539982, "n": 5028, "h": "c337dc3fcfa2d674", "c": "from __future__ import annotations\n\nimport json\nimport os\nimport sys\nfrom dataclasses import asdict, dataclass, field\nfrom pathlib import Path\n\n\nAPP_NAME = \"WeChatStyleReplyAssistant\"\n\n\ndef default_config_path() -> Path:\n if getattr(sys, \"frozen\", False):\n return Path(sys.executable).resolve().parent / \"user_data\" / \"settings.json\"\n base = os.environ.get(\"APPDATA\")\n if base:\n return Path(base) / APP_NAME / \"settings.json\"\n return Path.home() / \".wechat_style_reply_assistant\" / \"settings.json\"\n\n\n@dataclass\nclass ChatArea:\n x_left: float = 0.31\n x_right: float = 0.98\n y_top: float = 0.09\n y_bottom: float = 0.91\n\n\n@dataclass\nclass AppSettings:\n config_path: Path = field(default_factory=default_config_path)\n api_provider: str = \"zhipu\"\n api_key: str = \"\"\n base_url: str = \"https://open.bigmodel.cn/api/paas/v4\"\n model: str = \"glm-4-flash-250414\"\n vision_provider: str = \"zhipu\"\n vision_api_key: str = \"\"\n vision_base_url: str = \"https://open.bigmodel.cn/api/paas/v4\"\n vision_model: str = \"glm-4v-flash\"\n custom_headers: str = '{\"Authorization\":\"Bearer {api_key}\",\"Content-Type\":\"application/json\"}'\n custom_body: str = '{\"model\":\"{model}\",\"messages\":{messages_json}}'\n custom_response_path: str = \"choices.0.message.content\"\n reply_source_mode: str = \"model_memory\"\n ocr_engine: str = \"rapidocr\"\n training_mode: bool = False\n auto_recognize: bool = False\n managed_auto_reply: bool = False\n auto_reply_delay_seconds: float = 1.2\n poll_interval_ms: int = 1200\n capture_cooldown_seconds: float = 4.0\n chat_area: ChatArea = field(default_factory=ChatArea)\n\n def load(self) -> \"AppSettings\":\n if not self.config_path.exists():\n env_key = os.environ.get(\"TEXT_API_KEY\", \"\") or os.environ.get(\"ZHIPU_API_KEY\", \"\")\n if env_key:\n self.api_key = env_key\n return self\n\n data = json.loads(self.config_path.read_text(encoding=\"utf-8\"))\n self.api_provider = str(data.get(\"api_provider\", self.api_provider))\n self.api_key = str(data.get(\"api_key\", self.api_key))\n self.base_url = str(data.get(\"base_url\", self.base_url))\n self.model = str(data.get(\"model\", self.model))\n self.vision_provider = str(data.get(\"vision_provider\", self.vision_provider))\n self.vision_api_key = str(data.get(\"vision_api_key\", self.vision_api_key))\n self.vision_base_url = str(data.get(\"vision_base_url\", self.vision_base_url))\n self.vision_model = str(data.get(\"vision_model\", self.vision_model))\n if self.api_provider == \"zhipu\" and self.model in {\"glm-4.7-flash\", \"glm-4-flash\"}:\n self.model = \"glm-4-flash-250414\"\n self.custom_headers = str(data.get(\"custom_headers\", self.custom_headers))\n self.custom_body = str(data.get(\"custom_body\", self.custom_body))\n self.custom_response_path = str(data.get(\"custom_response_path\", self.custom_response_path))\n self.reply_source_mode = str(data.get(\"reply_source_mode\", self.reply_source_mode))\n if self.reply_source_mode not in {\"model\", \"memory\", \"model_memory\"}:\n self.reply_source_mode = \"model_memory\"\n self.ocr_engine = str(data.get(\"ocr_engine\", self.ocr_engine))\n self.training_mode = bool(data.get(\"training_mode\", self.training_mode))\n self.auto_recognize = bool(data.get(\"auto_recognize\", self.auto_recognize))\n self.managed_auto_reply = bool(data.get(\"managed_auto_reply\", self.managed_auto_reply))\n self.auto_reply_delay_seconds = float(data.get(\"auto_reply_delay_seconds\", self.auto_reply_delay_seconds))\n self.poll_interval_ms = int(data.get(\"poll_interval_ms\", self.poll_interval_ms))\n self.capture_cooldown_seconds = float(\n data.get(\"capture_cooldown_seconds\", self.capture_cooldown_seconds)\n )\n area = data.get(\"chat_area\", {})\n if isinstance(area, dict):\n self.chat_area = ChatArea(\n x_left=float(area.get(\"x_left\", self.chat_area.x_left)),\n x_right=float(area.get(\"x_right\", self.chat_area.x_right)),\n y_top=float(area.get(\"y_top\", self.chat_area.y_top)),\n y_bottom=float(area.get(\"y_bottom\", self.chat_area.y_bottom)),\n )\n if self.chat_area.x_left < 0.25:\n self.chat_area.x_left = ChatArea().x_left\n self.chat_area.x_right = ChatArea().x_right\n self.chat_area.y_top = ChatArea().y_top\n self.chat_area.y_bottom = ChatArea().y_bottom\n if self.chat_area.y_bottom < 0.90:\n self.chat_area.y_bottom = ChatArea().y_bottom\n return self\n\n def save(self) -> None:\n self.config_path.parent.mkdir(parents=True, exist_ok=True)\n data = asdict(self)\n data[\"config_path\"] = str(self.config_path)\n self.config_path.write_text(\n json.dumps(data, ensure_ascii=False, indent=2),\n encoding=\"utf-8\",\n )\n"}}, "README.md": {"c075ad81c6131c2cbc9ee3b571fea0bc6f92370e": {"t": 1785674182.7059174, "n": 848, "h": "8810aa11168f2d81", "c": "# 聊小智\n\n独立桌面程序。打开后会贴在微信窗口旁边,识别当前聊天上下文,生成候选回复,支持编辑、发送、训练模式、自动识别和全托管。\n\n## 使用方式\n\n1. 启动程序。\n2. 打开微信并点进某个具体聊天。\n3. 点“识别当前聊天”,程序会截图并用本地 OCR 识别最近几条消息。\n4. 程序生成 3 条候选回复,可点“改”编辑,也可点“发”直接发送。\n5. 发送成功后,最终发送文本和当时上下文会写入长期记忆。\n\n## 设置\n\n首次启动可在右上角“设置”里填写:\n\n- 智谱 API Key\n- Base URL:`https://open.bigmodel.cn/api/paas/v4`\n- 模型:`glm-4.7-flash`\n\n设置保存到:\n\n`%APPDATA%\\WeChatStyleReplyAssistant\\settings.json`\n\n## 导入聊天记录训练\n\n设置窗口里有“导入聊天记录训练包”按钮。\n\n训练包格式:\n\n```text\nA: 对方说的话\nB: 你希望程序学习的回复\nA: 对方下一句\nB: 你的下一句\n```\n\n可以把多个 `.txt` 放进一个文件夹,然后右键文件夹选择“发送到 > 压缩(zipped)文件夹”,生成 `.zip` 后导入。\n\n程序会保存 B 方回复前 5-8 轮完整上下文和真实回复,用于后续相似场景检索。长期记忆位置:\n\n`%APPDATA%\\WeChatStyleReplyAssistant\\memory.json`\n\n## 打包给别人用\n\n在项目目录执行:\n\n```bat\npython build_release.py\n```\n\n生成目录:\n\n`dist\\聊小智\\`\n\n把整个文件夹发给别人即可。对方解压后双击 `聊小智.exe` 或 `启动.bat`。\n\n## 依赖\n\n开发运行:\n\n```bat\npython -m pip install -r requirements.txt\npython main.py\n```\n"}}}} |