dyao-hippocortex 3.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dyao_hippocortex-3.0.1.dist-info/METADATA +128 -0
- dyao_hippocortex-3.0.1.dist-info/RECORD +89 -0
- dyao_hippocortex-3.0.1.dist-info/WHEEL +4 -0
- dyao_hippocortex-3.0.1.dist-info/licenses/LICENSE +4 -0
- hippocortex/BookReader.py +305 -0
- hippocortex/BrainBenchmark.py +345 -0
- hippocortex/BrainConfig.py +229 -0
- hippocortex/ChatThread.py +129 -0
- hippocortex/CognitiveEnergyField.py +92 -0
- hippocortex/Cognitive_system.py +214 -0
- hippocortex/ComponentFactory.py +97 -0
- hippocortex/Consolidation_loop.py +471 -0
- hippocortex/Curiosity.py +118 -0
- hippocortex/Data_models.py +867 -0
- hippocortex/DopamineSystem.py +370 -0
- hippocortex/Dreaming_loop.py +406 -0
- hippocortex/DummyBrain.py +186 -0
- hippocortex/DynamicExpert.py +1169 -0
- hippocortex/HippocampusRouter.py +479 -0
- hippocortex/ILifecycle.py +38 -0
- hippocortex/LLMBrainWrapper.py +361 -0
- hippocortex/LearnableSparseEncoderV2.py +196 -0
- hippocortex/Learning_loop.py +959 -0
- hippocortex/MainTest5.py +348 -0
- hippocortex/Metacognition.py +164 -0
- hippocortex/Multimodal_gateway.py +106 -0
- hippocortex/PerceptionLoop/BookReadingService.py +721 -0
- hippocortex/PerceptionLoop/CrossModalBridge.py +392 -0
- hippocortex/PerceptionLoop/IntentionService.py +317 -0
- hippocortex/PerceptionLoop/MindWanderingService.py +282 -0
- hippocortex/PerceptionLoop/ThinkEngine.py +536 -0
- hippocortex/PerceptionLoop/__init__.py +0 -0
- hippocortex/PersistentCortex.py +1253 -0
- hippocortex/ServiceContainer.py +107 -0
- hippocortex/StructureMapper.py +143 -0
- hippocortex/SymbolicCore.py +179 -0
- hippocortex/Thalamus.py +436 -0
- hippocortex/VAEManager.py +238 -0
- hippocortex/Wrappers/ConsolidationLoopWrapper.py +73 -0
- hippocortex/Wrappers/CuriosityWrapper.py +82 -0
- hippocortex/Wrappers/DopamineSystemWrapper.py +86 -0
- hippocortex/Wrappers/DreamingLoopWrapper.py +76 -0
- hippocortex/Wrappers/HippocampusRouterWrapper.py +45 -0
- hippocortex/Wrappers/LearningLoopWrapper.py +117 -0
- hippocortex/Wrappers/MetacognitionWrapper.py +68 -0
- hippocortex/Wrappers/PerceptionLoopWrapper.py +141 -0
- hippocortex/Wrappers/PersistentCortexWrapper.py +69 -0
- hippocortex/Wrappers/SymbolicCoreWrapper.py +48 -0
- hippocortex/Wrappers/ThalamusWrapper.py +65 -0
- hippocortex/Wrappers/VAEManagerWrapper.py +39 -0
- hippocortex/Wrappers/__init__.py +0 -0
- hippocortex/__init__.py +7 -0
- hippocortex/__main__.py +2 -0
- hippocortex/brain_core.py +65 -0
- hippocortex/brain_interface.py +197 -0
- hippocortex/brain_v13_demo/book_batch_summaries.json +1 -0
- hippocortex/brain_v13_demo/conversation_memory.json +6 -0
- hippocortex/brain_v13_demo/cortex_entity_index.json +13 -0
- hippocortex/brain_v13_demo/cortex_state.json +4 -0
- hippocortex/brain_v13_demo/cross_modal_bridges.pt +0 -0
- hippocortex/brain_v13_demo/cross_modal_dataset.pt +0 -0
- hippocortex/brain_v13_demo/expert_/321/206/320/232/342/225/234/321/210/342/226/222/320/261.pt +0 -0
- hippocortex/brain_v13_demo/expert_/321/206/320/266/320/222/321/205/342/224/220/342/225/241.pt +0 -0
- hippocortex/brain_v13_demo/expert_/321/207/320/271/342/225/221/321/211/320/247/342/224/244.pt +0 -0
- hippocortex/brain_v13_demo/expert_/321/210/320/267/320/226/321/210/320/267/320/231.pt +0 -0
- hippocortex/brain_v13_demo/expert_/321/210/342/225/221/320/273/321/204/342/225/227/342/225/234.pt +0 -0
- hippocortex/brain_v13_demo/hippocampus_router.pt +0 -0
- hippocortex/brain_v13_demo/important_entities.json +1 -0
- hippocortex/conversation_memory.py +341 -0
- hippocortex/event_system.py +137 -0
- hippocortex/imgs/error.png +0 -0
- hippocortex/imgs/sit.png +0 -0
- hippocortex/imgs/sit2.png +0 -0
- hippocortex/imgs/sleep.png +0 -0
- hippocortex/imgs/stand.png +0 -0
- hippocortex/imgs/swim.png +0 -0
- hippocortex/imgs/wandering01.png +0 -0
- hippocortex/imgs/wandering02.png +0 -0
- hippocortex/imgs/work.png +0 -0
- hippocortex/main.py +89 -0
- hippocortex/plugin_system.py +44 -0
- hippocortex/test.py +38 -0
- hippocortex/train_hippocampus.py +435 -0
- hippocortex/training_dataset.json +1587 -0
- hippocortex/ui/__init__.py +0 -0
- hippocortex/ui/brain_pet_window.py +584 -0
- hippocortex/ui/sleep_thread.py +33 -0
- hippocortex/utils/__init__.py +0 -0
- hippocortex/utils/heatmap_generator.py +216 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dyao-hippocortex
|
|
3
|
+
Version: 3.0.1
|
|
4
|
+
Summary: 一个模拟人类大脑结构的开源AI桌宠助手
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Keywords: ai,brain-simulation,neural-network,assistant,desktop-pet
|
|
7
|
+
Author: Yao Deng
|
|
8
|
+
Author-email: 2250111005@stu.hzcu.edu.cn
|
|
9
|
+
Requires-Python: >=3.11,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Dist: chardet (>=7.0.0)
|
|
20
|
+
Requires-Dist: diffusers (>=0.20.0)
|
|
21
|
+
Requires-Dist: faiss-cpu (>=1.14.0)
|
|
22
|
+
Requires-Dist: ipykernel (>=7.0.0)
|
|
23
|
+
Requires-Dist: ipython (>=8.0.0)
|
|
24
|
+
Requires-Dist: jieba (>=0.42.0)
|
|
25
|
+
Requires-Dist: langchain (>=0.2.0)
|
|
26
|
+
Requires-Dist: langchain-community (>=0.2.0)
|
|
27
|
+
Requires-Dist: langchain-core (>=0.2.0)
|
|
28
|
+
Requires-Dist: langchain-ollama (>=0.1.0)
|
|
29
|
+
Requires-Dist: langchain-text-splitters (>=0.2.0)
|
|
30
|
+
Requires-Dist: loguru (>=0.7.0)
|
|
31
|
+
Requires-Dist: matplotlib (>=3.8.0)
|
|
32
|
+
Requires-Dist: numpy (>=1.26.0)
|
|
33
|
+
Requires-Dist: pandas (>=2.0.0)
|
|
34
|
+
Requires-Dist: pillow (>=10.0.0)
|
|
35
|
+
Requires-Dist: pydantic (>=2.0.0)
|
|
36
|
+
Requires-Dist: pydantic-settings (>=2.0.0)
|
|
37
|
+
Requires-Dist: pygments (>=2.0.0)
|
|
38
|
+
Requires-Dist: pyqt5 (>=5.15.0)
|
|
39
|
+
Requires-Dist: python-dotenv (>=1.0.0)
|
|
40
|
+
Requires-Dist: scikit-learn (>=1.0.0)
|
|
41
|
+
Requires-Dist: scipy (>=1.11.0)
|
|
42
|
+
Requires-Dist: seaborn (>=0.13.0)
|
|
43
|
+
Requires-Dist: torch (>=2.0.0)
|
|
44
|
+
Requires-Dist: tqdm (>=4.66.0)
|
|
45
|
+
Requires-Dist: transformers (>=4.34.0)
|
|
46
|
+
Project-URL: Repository, https://github.com/a123547879/HippoCortex
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# 🧠 HippoCortex - 类脑AI桌宠助手
|
|
50
|
+
|
|
51
|
+
一个模拟人类大脑结构的开源AI桌宠助手,拥有自主意识、长期记忆和学习能力。
|
|
52
|
+
|
|
53
|
+
## ✨ 核心特性
|
|
54
|
+
|
|
55
|
+
- 🧠 **类脑认知架构**:模拟人脑海马体-皮层分工,多专家分区处理不同类型知识
|
|
56
|
+
- 💾 **长期记忆系统**:支持短期→长期→永久记忆分级,自然遗忘与睡眠巩固
|
|
57
|
+
- ⚡ **赫布学习机制**:遵循"共同激活,连接强化"原则,越用越聪明
|
|
58
|
+
- 🌙 **睡眠记忆巩固**:自动修剪无效突触,强化核心记忆,生成梦境
|
|
59
|
+
- 💬 **主动交互能力**:会主动说话、分享想法、提问,不是被动问答机器
|
|
60
|
+
- 🎨 **图文多模态**:支持图片理解和视觉想象,能"看到"并"想象"画面
|
|
61
|
+
- 📚 **自主学习能力**:会自己读书学习,不断增长知识
|
|
62
|
+
- 📊 **脑状态可视化**:实时显示疲劳度、记忆数、突触连接热力图
|
|
63
|
+
|
|
64
|
+
## 🚀 快速开始
|
|
65
|
+
|
|
66
|
+
### 前置要求
|
|
67
|
+
- Python 3.11+
|
|
68
|
+
- [Ollama](https://ollama.com/) 已安装并运行
|
|
69
|
+
|
|
70
|
+
### 安装
|
|
71
|
+
```bash
|
|
72
|
+
pip install hippocortex
|
|
73
|
+
|
|
74
|
+
运行
|
|
75
|
+
bash
|
|
76
|
+
运行
|
|
77
|
+
hippocortex
|
|
78
|
+
首次运行
|
|
79
|
+
程序会自动下载所需的 AI 模型:
|
|
80
|
+
gemma3:4b - 大语言模型
|
|
81
|
+
bge-m3 - 向量嵌入模型
|
|
82
|
+
🎮 使用说明
|
|
83
|
+
基本交互
|
|
84
|
+
点击桌宠头像打开聊天窗口
|
|
85
|
+
可以发送文字和图片
|
|
86
|
+
桌宠会根据对话内容学习和记忆
|
|
87
|
+
核心功能
|
|
88
|
+
聊天:自然语言对话,支持上下文理解
|
|
89
|
+
睡眠:点击 "睡眠" 按钮,让 AI 休息并巩固记忆
|
|
90
|
+
学习:AI 会在空闲时自动读书学习
|
|
91
|
+
走神:AI 空闲时会进入走神状态,回忆和联想记忆
|
|
92
|
+
分析:右键菜单可以分析大脑突触连接热力图
|
|
93
|
+
🧠 大脑状态说明
|
|
94
|
+
表格
|
|
95
|
+
状态 说明
|
|
96
|
+
🧠 大脑已唤醒 正常工作状态
|
|
97
|
+
🌙 走神中... 正在回忆和联想记忆
|
|
98
|
+
💬 有话想对你说... 有主动意图要表达
|
|
99
|
+
🌙 睡眠巩固中... 正在睡眠,整理记忆
|
|
100
|
+
❌ 思考失败 遇到错误
|
|
101
|
+
🛠️ 开发
|
|
102
|
+
本地运行
|
|
103
|
+
bash
|
|
104
|
+
运行
|
|
105
|
+
git clone https://github.com/a123547879/HippoCortex.git
|
|
106
|
+
cd HippoCortex
|
|
107
|
+
pip install -r requirements.txt
|
|
108
|
+
cd src
|
|
109
|
+
python MainTest5.py
|
|
110
|
+
项目结构
|
|
111
|
+
plaintext
|
|
112
|
+
hippocortex/
|
|
113
|
+
├── core/ # 核心认知模块
|
|
114
|
+
│ ├── BrainCore.py # 大脑核心
|
|
115
|
+
│ ├── Hippocampus.py # 海马体
|
|
116
|
+
│ └── Cortex.py # 大脑皮层
|
|
117
|
+
├── experts/ # 多专家系统
|
|
118
|
+
│ ├── ConceptExpert.py
|
|
119
|
+
│ ├── SpatialExpert.py
|
|
120
|
+
│ ├── AbstractExpert.py
|
|
121
|
+
│ └── VisualExpert.py
|
|
122
|
+
├── services/ # 服务模块
|
|
123
|
+
│ ├── IntentionService.py
|
|
124
|
+
│ ├── MindWanderingService.py
|
|
125
|
+
│ └── BookReadingService.py
|
|
126
|
+
├── ui/ # 用户界面
|
|
127
|
+
│ └── brain_pet_window.py
|
|
128
|
+
└── main.py # 程序入口
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
hippocortex/__init__.py,sha256=9NXi3Dyg7Bcew_7O6r1D6O52U5BeczfJTctLjABm6a4,173
|
|
2
|
+
hippocortex/__main__.py,sha256=2Tw6mLLGOZM-K97fW3ugTIBdpYIEvXiEkTZ6wF4i48k,30
|
|
3
|
+
hippocortex/BookReader.py,sha256=zXXqYctCQ4dpJlXprF4thBrfsNr9o7TJOyU8Cl0DrNY,13482
|
|
4
|
+
hippocortex/brain_core.py,sha256=tpi1rczwWErOxCzXd9Qbz3UPJDcK4CXfm1cHEpCig3M,2127
|
|
5
|
+
hippocortex/brain_interface.py,sha256=AuG1QcRihoPInT77ZpEDkpH5HyqSvjVj4w2wFY1CQlk,7912
|
|
6
|
+
hippocortex/brain_v13_demo/book_batch_summaries.json,sha256=RBNvo1WzZ4oRRq0W9-hknpT7T8If536DEMBg9hyq_4o,2
|
|
7
|
+
hippocortex/brain_v13_demo/conversation_memory.json,sha256=B568G3FPg5xjwdpD94H7RBdhxpNEFY4u1IDfr8NIig0,112
|
|
8
|
+
hippocortex/brain_v13_demo/cortex_entity_index.json,sha256=rdevIsOZApieFxcvr3Sysib6__j2IbFy_I-dQiJOGLE,256
|
|
9
|
+
hippocortex/brain_v13_demo/cortex_state.json,sha256=fzvjL2Fxue-shr-inorqWYGbUyqbTbXmLrFGAkT5C9Y,53
|
|
10
|
+
hippocortex/brain_v13_demo/cross_modal_bridges.pt,sha256=TO-Psmv6pwwFiIepIjVqm5PvSO5dzd7T7EHvz3dtQQo,167860922
|
|
11
|
+
hippocortex/brain_v13_demo/cross_modal_dataset.pt,sha256=YB7BG0prAyjz6GOecY8ccI6nKdZLksh30jy8IAvQICY,1040
|
|
12
|
+
hippocortex/brain_v13_demo/expert_抽象.pt,sha256=DYnlzSRaRE4_sRy0b0-gzwZLwZMt5jUzk1IeGLIPVpw,50346192
|
|
13
|
+
hippocortex/brain_v13_demo/expert_概念.pt,sha256=coxNgEkowvqNUoX1sr8y0swLStGaFck8NtWYeWMLr74,50346192
|
|
14
|
+
hippocortex/brain_v13_demo/expert_空间.pt,sha256=NobzxgxdMTWMoeNfjeETFOXVyHTHO_ywixEOsjlJprg,50346192
|
|
15
|
+
hippocortex/brain_v13_demo/expert_视觉.pt,sha256=CK8LgIQFH5Ff95FlOZbAMB6sotT9KUz1pJ1SaVDXn8Q,50346192
|
|
16
|
+
hippocortex/brain_v13_demo/expert_身份.pt,sha256=5ycEDGEqWMnurDn-B_gB4vD86TdwpA65r9Ov77iULuU,50346192
|
|
17
|
+
hippocortex/brain_v13_demo/hippocampus_router.pt,sha256=RZobMSxHV1NEsVICol42XW1BqdL8URE9ly0gGpIzVDo,1082394
|
|
18
|
+
hippocortex/brain_v13_demo/important_entities.json,sha256=T1PNoYwrqgwDVLtfmj7L5e0Sq02OEbqHPC8RFhICuUU,2
|
|
19
|
+
hippocortex/BrainBenchmark.py,sha256=15XnVQpzlS4EDjk_YJf-wB9TFFlWWFoIQJZcn1ADlpI,14270
|
|
20
|
+
hippocortex/BrainConfig.py,sha256=eVhPA_c-3DUNXLfTQP4tItEExLM3ipZJbBSO9Eci4DY,11161
|
|
21
|
+
hippocortex/ChatThread.py,sha256=LllsT89SQ5YE5BxsXpyI2ApDSsBALT8iHo7EH7Rt8Sc,6317
|
|
22
|
+
hippocortex/Cognitive_system.py,sha256=BcntAkhhvJkjB1L-SPPScM71CclYPkUE7vyECrL1jSw,7921
|
|
23
|
+
hippocortex/CognitiveEnergyField.py,sha256=xnIQsGr9MpSni6FeuuYLtCbIu4B5w9tZFs6JuwW78tc,3667
|
|
24
|
+
hippocortex/ComponentFactory.py,sha256=naE8c2F1-QEtXAT0vMiwD45cW9NkYtiZ-PLREuTXLCY,4525
|
|
25
|
+
hippocortex/Consolidation_loop.py,sha256=gzWN7RxBXv7SBy8GqCDuinQvEkKgklkD3tmL6t9CMrY,23960
|
|
26
|
+
hippocortex/conversation_memory.py,sha256=XB5OJA8pA4B_XRKW9gjH18L7j2KLxZomrgQa6sW3DJ0,15755
|
|
27
|
+
hippocortex/Curiosity.py,sha256=etNJz6L-jiyJw_yRaZwZV-mjVI-ZbCQV-64gsMhJHKw,4537
|
|
28
|
+
hippocortex/Data_models.py,sha256=vnY9ffoEQNIl0LbYmQ34TycslUCyirRN_XT1Xzcq8JM,30422
|
|
29
|
+
hippocortex/DopamineSystem.py,sha256=U_UKzrBOXNDA0t4coCc47Wyl9VuO1FpkpNDmSQnAlYA,15909
|
|
30
|
+
hippocortex/Dreaming_loop.py,sha256=S36Cxu29Vw3EDCSoHOJjKKBl7Q-25viNO99c3iI77tU,19919
|
|
31
|
+
hippocortex/DummyBrain.py,sha256=2dAggt8NAu1EBuEYghWR2AbUo58W7lexW9eNi_UgYu0,8093
|
|
32
|
+
hippocortex/DynamicExpert.py,sha256=dH51xNZOHQFfq8hmmH-hURl9M7BGvJ-IWEPWNtb_8vY,55470
|
|
33
|
+
hippocortex/event_system.py,sha256=0G-J8ZYGg5J4fVbI3SlFXTZ5bmJ00HvIB8mylgLHc8M,4440
|
|
34
|
+
hippocortex/HippocampusRouter.py,sha256=KVXMoA2Fe876QhKhN7fh6o6tOUwURYBn3UxUdZxyZPw,23782
|
|
35
|
+
hippocortex/ILifecycle.py,sha256=jbXw9AJJsjGzb_kcp9yHZ5_--GIP_oxIcf20URPwXfc,940
|
|
36
|
+
hippocortex/imgs/error.png,sha256=AQg7UD6ENEmwZOaysenRQAPj7HuhRFI6FGcnAHDg2ZQ,2255698
|
|
37
|
+
hippocortex/imgs/sit.png,sha256=7nG2DVUwchCuL7uuu7Dn-AlY1A2kqqwQiBP6wGHmaiY,1699219
|
|
38
|
+
hippocortex/imgs/sit2.png,sha256=a-8lw87l3BUGHsNdSbkwR0Cv62RJC_zblaRnJDFXsAI,1611273
|
|
39
|
+
hippocortex/imgs/sleep.png,sha256=I1_xClvwjecL1neb9vVD8adLSXBHzt63dgQGKin69Pw,1862491
|
|
40
|
+
hippocortex/imgs/stand.png,sha256=IxWVj0X4fepgoTAzQdnY7jRPjICq0p8sYWkbXgyna6U,1885469
|
|
41
|
+
hippocortex/imgs/swim.png,sha256=XxV_4qALE1bVrHKDaWf6wY5H4RDN4XckYve5L6b2dgQ,1673683
|
|
42
|
+
hippocortex/imgs/wandering01.png,sha256=Lb9eF17adormSYkKajuwrwsVYNkOhLd682OiV_NyEqY,1654468
|
|
43
|
+
hippocortex/imgs/wandering02.png,sha256=N83foeeh2m51V6VuNkkUDAswXwxUq6TfixZBeTPmNm8,2111221
|
|
44
|
+
hippocortex/imgs/work.png,sha256=G99jOH9p3aQLD7OdXvlOK-4CwNDlvAYjypyp2TD4RuQ,1489410
|
|
45
|
+
hippocortex/LearnableSparseEncoderV2.py,sha256=yE1SAw92lhcML7PcXHli_hLhwS3N7JWbYAzT31PZchE,7127
|
|
46
|
+
hippocortex/Learning_loop.py,sha256=bhCKTa7HNC_VD4nEm43KHNQYwzbPZaWH0dAmmghMJgY,47069
|
|
47
|
+
hippocortex/LLMBrainWrapper.py,sha256=c0_L4jndkow_IgiLTGB7oYeK53GC_ek3EqV9f-z1Bro,20130
|
|
48
|
+
hippocortex/main.py,sha256=4_HvFGPDzfE5yxwkXfZOzQ8BUgTBdpYG1jitqC3rxOg,3311
|
|
49
|
+
hippocortex/MainTest5.py,sha256=4gtaf8kpgVu9Y1aWwl5kuGPu3-WX6aH3Yd13cpOVULU,14292
|
|
50
|
+
hippocortex/Metacognition.py,sha256=Ye6hZ_uIgYjZdEnS7OkzA6Vsk7CU5OVtaDhoBdBaRPE,6395
|
|
51
|
+
hippocortex/Multimodal_gateway.py,sha256=3MkhYXT0Do7DIWo47IMwanKdLhGahtN_aQNYExzf14o,4705
|
|
52
|
+
hippocortex/PerceptionLoop/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
hippocortex/PerceptionLoop/BookReadingService.py,sha256=zZcuNCnz3dQxbRr1KlyM_K3Db0yyXDi8ewDpv5jmqYM,36695
|
|
54
|
+
hippocortex/PerceptionLoop/CrossModalBridge.py,sha256=52EUTMecXuaHHpVq1mquD1t4CpEVUyqJ1uQLHSE_89Q,18892
|
|
55
|
+
hippocortex/PerceptionLoop/IntentionService.py,sha256=jSVelUd_pOFLHoho-A8UFChGpYIxc7ZNiOoinVBwKvE,14344
|
|
56
|
+
hippocortex/PerceptionLoop/MindWanderingService.py,sha256=v6Ogdb11FImuwCLRwt2eYZBQVC0oPkvQgEwmc30-YXU,12274
|
|
57
|
+
hippocortex/PerceptionLoop/ThinkEngine.py,sha256=H1PU9d289316fYmqltGt3z-rOQfPdeidRoD3pd2f6zE,24000
|
|
58
|
+
hippocortex/PersistentCortex.py,sha256=xsls51NmEonJJonelMgWtE9AGeCf9uBYO7Y4ThQUyYk,57034
|
|
59
|
+
hippocortex/plugin_system.py,sha256=6YlBr1WLw5ComhzXMWWXsNYGH8enu3KS4JrefTB4P3Y,990
|
|
60
|
+
hippocortex/ServiceContainer.py,sha256=3HR2Epjerb58MR2R1Ec98h0Fvf4YxEgOUuAd1eN6z54,4252
|
|
61
|
+
hippocortex/StructureMapper.py,sha256=KKdimLwlCnuHp0lQoy7bckppeMLtV-Ua8mBTS9WCqXE,5864
|
|
62
|
+
hippocortex/SymbolicCore.py,sha256=sj3d299yRdVMpJCB7OoBxmY1wRzIFbwIpjDUndcZVP8,6964
|
|
63
|
+
hippocortex/test.py,sha256=903BJApift3svzqKNnGUKubcXEQQWsZZGjPnkURVM-8,1421
|
|
64
|
+
hippocortex/Thalamus.py,sha256=0h5MfVLPBmLIN-Ox4NlKOtZae3N2EpTg2k4Pv5G81I4,18144
|
|
65
|
+
hippocortex/train_hippocampus.py,sha256=Q3SUnaN5ZLC4B1e3-kCZVIzxUorMKU-NdRu3_ir-yQA,17037
|
|
66
|
+
hippocortex/training_dataset.json,sha256=yArY8Ze8VoNyGEy-w3YS_7TYPsTLHUiTpAUtPd5PHAU,32240
|
|
67
|
+
hippocortex/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
|
+
hippocortex/ui/brain_pet_window.py,sha256=_hkd0xkeM49C0Z-emy-uXXG6-MaVOL1IYqc_UATjy-0,24256
|
|
69
|
+
hippocortex/ui/sleep_thread.py,sha256=YsOSabYHlUMfV0H2oP0wo5fQ5x7HqtCdOCUBv1gtlZc,1294
|
|
70
|
+
hippocortex/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
+
hippocortex/utils/heatmap_generator.py,sha256=Lbbc-igIUnrZ9EMHrtw7tnfPsLOGbke_eBOW260C2p8,9473
|
|
72
|
+
hippocortex/VAEManager.py,sha256=ZDZpKbtk0cjvhruSRxIjlkxeIVQwm-4GKmP3g92h_JA,10554
|
|
73
|
+
hippocortex/Wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
+
hippocortex/Wrappers/ConsolidationLoopWrapper.py,sha256=irgVNuf1LglEKnNfPvIkxz7vTwvCtBSanLFSkfpw0XM,3048
|
|
75
|
+
hippocortex/Wrappers/CuriosityWrapper.py,sha256=VzuZkGz6sDR_ozOtyS-JZ3ml72ORjLSmJRnJdptQg5I,3577
|
|
76
|
+
hippocortex/Wrappers/DopamineSystemWrapper.py,sha256=QwmuLrFSUem73RnTcBGqNTNewYlFqrHzx16MKWozZWs,3903
|
|
77
|
+
hippocortex/Wrappers/DreamingLoopWrapper.py,sha256=Q6wWCc6KXGZznVQdjzOInNLanzG5EuYDeUVrdWhXPHQ,2504
|
|
78
|
+
hippocortex/Wrappers/HippocampusRouterWrapper.py,sha256=1dc9y_pmEW8quZ1gCpxtomqv2x_yDMvWyURT9iVH2F0,1773
|
|
79
|
+
hippocortex/Wrappers/LearningLoopWrapper.py,sha256=E-e-rQWVWSUlrkI1m3-hwRAH-Law6ZbGG6DIgNzjG9U,4936
|
|
80
|
+
hippocortex/Wrappers/MetacognitionWrapper.py,sha256=vNbyMgyByC8iX15cGhxhcVbV_BfUKyawSKX0SVXqaCE,2991
|
|
81
|
+
hippocortex/Wrappers/PerceptionLoopWrapper.py,sha256=YgJP34U1r8gKWPuxQvzaQxQre0b8oq54cKh7ST9E5_c,5702
|
|
82
|
+
hippocortex/Wrappers/PersistentCortexWrapper.py,sha256=OL7fKLJnJoMiMITjyHD8jR_xyd3yJ3ZeAboA6nfbvag,2817
|
|
83
|
+
hippocortex/Wrappers/SymbolicCoreWrapper.py,sha256=jN_qgCbtGuTMKybYZkbMW6Hr9QRikCJxsK8P_n4Xghk,1872
|
|
84
|
+
hippocortex/Wrappers/ThalamusWrapper.py,sha256=or3l4N-gwx6qNfb98kIJpJQI56Z-HetHIfVB_EyUIcM,2361
|
|
85
|
+
hippocortex/Wrappers/VAEManagerWrapper.py,sha256=c2zB2auWAXp5Mdb5WwYVIvnhYo6TsdmDdK9fS0B1uPQ,1193
|
|
86
|
+
dyao_hippocortex-3.0.1.dist-info/licenses/LICENSE,sha256=8Jb_oCEl09ac7RQniOkH9uGigG9CfpbUsJ0SRpHaXbg,1039
|
|
87
|
+
dyao_hippocortex-3.0.1.dist-info/METADATA,sha256=n_eRTQjEs4d_RznvKtksx8br_9M7-bIN-dTEzLASoHE,4610
|
|
88
|
+
dyao_hippocortex-3.0.1.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
|
|
89
|
+
dyao_hippocortex-3.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Copyright (c) 2026 Yao Deng
|
|
2
|
+
Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:
|
|
3
|
+
The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
|
|
4
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE.
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
import random
|
|
4
|
+
import chardet
|
|
5
|
+
from typing import Optional, List, Dict, Tuple
|
|
6
|
+
import logging
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger("BookReader")
|
|
10
|
+
|
|
11
|
+
# 阅读进度配置文件
|
|
12
|
+
PROGRESS_FILE = "book_read_progress.json"
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class BookPage:
|
|
16
|
+
"""强类型书籍页面,与系统整体数据契约保持一致"""
|
|
17
|
+
book_name: str
|
|
18
|
+
content: str
|
|
19
|
+
current_progress: float # 0.0-1.0
|
|
20
|
+
is_new_cycle: bool = False # 是否刚读完一整遍重新开始
|
|
21
|
+
|
|
22
|
+
class BookReader:
|
|
23
|
+
def __init__(self, book_dir: str = "./books"):
|
|
24
|
+
self.book_dir = book_dir
|
|
25
|
+
self.progress = self._load_progress()
|
|
26
|
+
self.blacklist: Dict[str, int] = {} # 书籍黑名单:{书名: 失败次数}
|
|
27
|
+
self.MAX_FAILURES = 3 # 连续失败3次加入黑名单
|
|
28
|
+
|
|
29
|
+
# ===================== 🔥 新增:阅读配置开关 =====================
|
|
30
|
+
self.use_paragraph_alignment: bool = True # 智能段落对齐
|
|
31
|
+
self.use_weighted_random: bool = True # 加权随机选书
|
|
32
|
+
self.auto_encoding_detect: bool = True # 自动编码检测
|
|
33
|
+
self.mark_new_cycle: bool = True # 标记新阅读周期
|
|
34
|
+
# ==================================================================
|
|
35
|
+
|
|
36
|
+
# 自动创建图书文件夹
|
|
37
|
+
if not os.path.exists(book_dir):
|
|
38
|
+
os.makedirs(book_dir)
|
|
39
|
+
logger.info(f"📚 已自动创建图书文件夹: {book_dir},请放入txt小说")
|
|
40
|
+
|
|
41
|
+
def _load_progress(self) -> Dict:
|
|
42
|
+
"""加载阅读进度(空值安全+版本兼容)"""
|
|
43
|
+
if os.path.exists(PROGRESS_FILE):
|
|
44
|
+
try:
|
|
45
|
+
with open(PROGRESS_FILE, "r", encoding="utf-8") as f:
|
|
46
|
+
data = json.load(f)
|
|
47
|
+
# 兼容旧版进度格式(纯字节位置)
|
|
48
|
+
cleaned_data = {}
|
|
49
|
+
for k, v in data.items():
|
|
50
|
+
if isinstance(v, (int, float)):
|
|
51
|
+
cleaned_data[k] = {"pos": int(v), "file_size": 0}
|
|
52
|
+
else:
|
|
53
|
+
cleaned_data[k] = v
|
|
54
|
+
return cleaned_data
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logger.error(f"阅读进度文件损坏,重新初始化: {e}")
|
|
57
|
+
return {}
|
|
58
|
+
return {}
|
|
59
|
+
|
|
60
|
+
def _save_progress(self):
|
|
61
|
+
"""保存阅读进度(原子写入,避免文件损坏)"""
|
|
62
|
+
try:
|
|
63
|
+
temp_file = PROGRESS_FILE + ".tmp"
|
|
64
|
+
with open(temp_file, "w", encoding="utf-8") as f:
|
|
65
|
+
json.dump(self.progress, f, ensure_ascii=False, indent=2)
|
|
66
|
+
os.replace(temp_file, PROGRESS_FILE)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
logger.error(f"保存阅读进度失败: {e}")
|
|
69
|
+
|
|
70
|
+
def get_all_books(self) -> List[str]:
|
|
71
|
+
"""获取所有有效txt书籍(过滤空文件和黑名单)"""
|
|
72
|
+
valid_books = []
|
|
73
|
+
for f in os.listdir(self.book_dir):
|
|
74
|
+
if f.endswith(".txt"):
|
|
75
|
+
file_path = os.path.join(self.book_dir, f)
|
|
76
|
+
if os.path.getsize(file_path) > 1024:
|
|
77
|
+
# 排除连续失败超过阈值的书
|
|
78
|
+
if self.blacklist.get(f, 0) < self.MAX_FAILURES:
|
|
79
|
+
valid_books.append(f)
|
|
80
|
+
return valid_books
|
|
81
|
+
|
|
82
|
+
def _detect_encoding(self, file_path: str) -> str:
|
|
83
|
+
"""自动检测文件编码(UTF-8/GBK)"""
|
|
84
|
+
if not self.auto_encoding_detect:
|
|
85
|
+
return "utf-8"
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
with open(file_path, "rb") as f:
|
|
89
|
+
raw = f.read(10000) # 读取前10KB检测编码
|
|
90
|
+
result = chardet.detect(raw)
|
|
91
|
+
encoding = result["encoding"] or "utf-8"
|
|
92
|
+
# 统一常见编码名称
|
|
93
|
+
if encoding.lower() in ["gb2312", "gb18030"]:
|
|
94
|
+
encoding = "gbk"
|
|
95
|
+
logger.debug(f"📖 检测到《{os.path.basename(file_path)}》编码: {encoding}")
|
|
96
|
+
return encoding
|
|
97
|
+
except Exception as e:
|
|
98
|
+
logger.debug(f"编码检测失败,使用默认UTF-8: {e}")
|
|
99
|
+
return "utf-8"
|
|
100
|
+
|
|
101
|
+
def read_book_page(self, book_name: str, page_size: int = 600) -> Optional[BookPage]:
|
|
102
|
+
"""
|
|
103
|
+
分页阅读书籍(终极优化版)
|
|
104
|
+
✅ 自动编码检测(UTF-8/GBK)
|
|
105
|
+
✅ 智能段落对齐
|
|
106
|
+
✅ 文件变化自动重置进度
|
|
107
|
+
✅ 读完自动从头开始并标记新周期
|
|
108
|
+
"""
|
|
109
|
+
book_path = os.path.join(self.book_dir, book_name)
|
|
110
|
+
if not os.path.exists(book_path):
|
|
111
|
+
logger.warning(f"书籍不存在: {book_name}")
|
|
112
|
+
self.blacklist[book_name] = self.blacklist.get(book_name, 0) + 1
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
# 获取文件大小,用于计算进度和检测文件变化
|
|
116
|
+
file_size = os.path.getsize(book_path)
|
|
117
|
+
book_progress = self.progress.get(book_name, {"pos": 0, "file_size": 0})
|
|
118
|
+
current_pos = book_progress["pos"]
|
|
119
|
+
saved_file_size = book_progress["file_size"]
|
|
120
|
+
|
|
121
|
+
# 检测到文件内容变化,自动重置进度
|
|
122
|
+
if saved_file_size != 0 and saved_file_size != file_size:
|
|
123
|
+
logger.info(f"📖 《{book_name}》文件内容已变化,自动重置阅读进度")
|
|
124
|
+
current_pos = 0
|
|
125
|
+
|
|
126
|
+
is_new_cycle = False
|
|
127
|
+
try:
|
|
128
|
+
encoding = self._detect_encoding(book_path)
|
|
129
|
+
|
|
130
|
+
with open(book_path, "rb") as f:
|
|
131
|
+
f.seek(current_pos)
|
|
132
|
+
# 多读3字节防止汉字截断,多读100字节用于段落对齐
|
|
133
|
+
raw_bytes = f.read(page_size + 103)
|
|
134
|
+
|
|
135
|
+
# 读完自动重置进度
|
|
136
|
+
if not raw_bytes or len(raw_bytes.strip()) == 0:
|
|
137
|
+
logger.info(f"📖 《{book_name}》 已读完,自动从头开始阅读")
|
|
138
|
+
current_pos = 0
|
|
139
|
+
is_new_cycle = True
|
|
140
|
+
f.seek(0)
|
|
141
|
+
raw_bytes = f.read(page_size + 103)
|
|
142
|
+
if not raw_bytes:
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
# 修复UTF-8汉字截断
|
|
146
|
+
valid_end = len(raw_bytes)
|
|
147
|
+
while valid_end > 0 and (raw_bytes[valid_end-1] & 0xC0) == 0x80:
|
|
148
|
+
valid_end -= 1
|
|
149
|
+
|
|
150
|
+
# 解码为字符串
|
|
151
|
+
content = raw_bytes[:valid_end].decode(encoding, errors="replace").strip()
|
|
152
|
+
|
|
153
|
+
# ===================== 🔥 新增:智能段落对齐 =====================
|
|
154
|
+
if self.use_paragraph_alignment and valid_end < len(raw_bytes):
|
|
155
|
+
# 寻找最后一个段落结束符(换行/句号/感叹号/问号)
|
|
156
|
+
paragraph_ends = [
|
|
157
|
+
content.rfind("\n"),
|
|
158
|
+
content.rfind("。"),
|
|
159
|
+
content.rfind("!"),
|
|
160
|
+
content.rfind("?"),
|
|
161
|
+
content.rfind(";")
|
|
162
|
+
]
|
|
163
|
+
last_paragraph_end = max(paragraph_ends)
|
|
164
|
+
|
|
165
|
+
# 如果找到段落结束符,并且截断位置在页面的后30%,就截断到段落结束
|
|
166
|
+
if last_paragraph_end > int(page_size * 0.7):
|
|
167
|
+
content = content[:last_paragraph_end + 1].strip()
|
|
168
|
+
valid_end = len(raw_bytes[:valid_end].decode(encoding, errors="replace")[:last_paragraph_end + 1].encode(encoding))
|
|
169
|
+
# ==================================================================
|
|
170
|
+
|
|
171
|
+
# 清理乱码和特殊字符
|
|
172
|
+
import re
|
|
173
|
+
content = re.sub(r'[�\x00-\x1F\x7F]+', '', content)
|
|
174
|
+
content = re.sub(r'\n+', '\n', content) # 合并多余换行
|
|
175
|
+
|
|
176
|
+
# 过滤过短的无效内容
|
|
177
|
+
if len(content) < 20:
|
|
178
|
+
logger.debug(f"跳过过短内容: {book_name} 位置:{current_pos}")
|
|
179
|
+
new_pos = current_pos + valid_end
|
|
180
|
+
self.progress[book_name] = {"pos": new_pos, "file_size": file_size}
|
|
181
|
+
self._save_progress()
|
|
182
|
+
return self.read_book_page(book_name, page_size)
|
|
183
|
+
|
|
184
|
+
# 更新进度
|
|
185
|
+
new_pos = current_pos + valid_end
|
|
186
|
+
self.progress[book_name] = {"pos": new_pos, "file_size": file_size}
|
|
187
|
+
self._save_progress()
|
|
188
|
+
|
|
189
|
+
# 重置失败计数
|
|
190
|
+
self.blacklist[book_name] = 0
|
|
191
|
+
|
|
192
|
+
# 计算阅读进度百分比
|
|
193
|
+
progress_percent = min(1.0, new_pos / file_size) if file_size > 0 else 0.0
|
|
194
|
+
|
|
195
|
+
return BookPage(
|
|
196
|
+
book_name=book_name,
|
|
197
|
+
content=content,
|
|
198
|
+
current_progress=progress_percent,
|
|
199
|
+
is_new_cycle=is_new_cycle
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
except Exception as e:
|
|
203
|
+
logger.error(f"读取书籍《{book_name}》失败: {e}", exc_info=True)
|
|
204
|
+
self.blacklist[book_name] = self.blacklist.get(book_name, 0) + 1
|
|
205
|
+
|
|
206
|
+
# 出错时跳过当前位置
|
|
207
|
+
new_pos = current_pos + page_size
|
|
208
|
+
self.progress[book_name] = {"pos": new_pos, "file_size": file_size}
|
|
209
|
+
self._save_progress()
|
|
210
|
+
|
|
211
|
+
# 如果连续失败超过阈值,加入黑名单
|
|
212
|
+
if self.blacklist[book_name] >= self.MAX_FAILURES:
|
|
213
|
+
logger.warning(f"📖 《{book_name}》连续失败{self.MAX_FAILURES}次,已加入黑名单")
|
|
214
|
+
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
def random_read(self) -> Optional[Dict]:
|
|
218
|
+
"""
|
|
219
|
+
随机选一本书阅读一段(加权随机+新周期事件)
|
|
220
|
+
✅ 优先读进度少的书
|
|
221
|
+
✅ 读完一本书自动生成读完记忆
|
|
222
|
+
✅ 兼容原有返回格式
|
|
223
|
+
"""
|
|
224
|
+
books = self.get_all_books()
|
|
225
|
+
if not books:
|
|
226
|
+
logger.info("📚 未找到任何有效书籍")
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
# 加权随机选书:进度越少,权重越高
|
|
230
|
+
if self.use_weighted_random:
|
|
231
|
+
book_weights = []
|
|
232
|
+
for book in books:
|
|
233
|
+
book_progress = self.progress.get(book, {"pos": 0, "file_size": 0})
|
|
234
|
+
pos = book_progress["pos"]
|
|
235
|
+
file_size = book_progress["file_size"] or os.path.getsize(os.path.join(self.book_dir, book))
|
|
236
|
+
progress = pos / file_size if file_size > 0 else 0.0
|
|
237
|
+
# 权重 = 1 - 进度,进度越少权重越高
|
|
238
|
+
weight = max(0.1, 1.0 - progress)
|
|
239
|
+
book_weights.append(weight)
|
|
240
|
+
|
|
241
|
+
# 归一化权重
|
|
242
|
+
total_weight = sum(book_weights)
|
|
243
|
+
normalized_weights = [w / total_weight for w in book_weights]
|
|
244
|
+
|
|
245
|
+
# 加权随机选择
|
|
246
|
+
book = random.choices(books, weights=normalized_weights, k=1)[0]
|
|
247
|
+
else:
|
|
248
|
+
# 纯随机选书(原有逻辑)
|
|
249
|
+
book = random.choice(books)
|
|
250
|
+
|
|
251
|
+
# 读取页面
|
|
252
|
+
page = self.read_book_page(book)
|
|
253
|
+
if not page:
|
|
254
|
+
# 失败时重试其他书
|
|
255
|
+
for _ in range(2):
|
|
256
|
+
other_books = [b for b in books if b != book]
|
|
257
|
+
if not other_books:
|
|
258
|
+
break
|
|
259
|
+
book = random.choice(other_books)
|
|
260
|
+
page = self.read_book_page(book)
|
|
261
|
+
if page:
|
|
262
|
+
break
|
|
263
|
+
|
|
264
|
+
if not page:
|
|
265
|
+
logger.warning("📚 所有书籍都无法读取有效内容,请检查txt文件是否正常")
|
|
266
|
+
return None
|
|
267
|
+
|
|
268
|
+
# 读完一整本书时,生成读完记忆
|
|
269
|
+
if page.is_new_cycle and self.mark_new_cycle:
|
|
270
|
+
logger.info(f"🎉 已读完《{page.book_name}》一整遍!")
|
|
271
|
+
# 这里可以触发事件总线,让大脑生成读完记忆
|
|
272
|
+
# self.event_bus.emit(Event("BOOK_FINISHED", {"book_name": page.book_name}))
|
|
273
|
+
|
|
274
|
+
# 兼容原有返回格式,上层代码完全不用改
|
|
275
|
+
return {
|
|
276
|
+
"book_name": page.book_name,
|
|
277
|
+
"content": page.content,
|
|
278
|
+
"progress": page.current_progress,
|
|
279
|
+
"is_new_cycle": page.is_new_cycle
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
def get_book_progress(self, book_name: str) -> float:
|
|
283
|
+
"""获取指定书籍的阅读进度(0.0-1.0)"""
|
|
284
|
+
book_path = os.path.join(self.book_dir, book_name)
|
|
285
|
+
if not os.path.exists(book_path):
|
|
286
|
+
return 0.0
|
|
287
|
+
|
|
288
|
+
file_size = os.path.getsize(book_path)
|
|
289
|
+
if file_size == 0:
|
|
290
|
+
return 0.0
|
|
291
|
+
|
|
292
|
+
book_progress = self.progress.get(book_name, {"pos": 0, "file_size": 0})
|
|
293
|
+
return min(1.0, book_progress["pos"] / file_size)
|
|
294
|
+
|
|
295
|
+
def reset_book_progress(self, book_name: str) -> None:
|
|
296
|
+
"""重置指定书籍的阅读进度"""
|
|
297
|
+
if book_name in self.progress:
|
|
298
|
+
del self.progress[book_name]
|
|
299
|
+
self._save_progress()
|
|
300
|
+
logger.info(f"📖 已重置《{book_name}》的阅读进度")
|
|
301
|
+
|
|
302
|
+
def clear_blacklist(self) -> None:
|
|
303
|
+
"""清空书籍黑名单"""
|
|
304
|
+
self.blacklist.clear()
|
|
305
|
+
logger.info("📚 已清空书籍黑名单")
|