Releases: 2002yy/study-agent
Releases · 2002yy/study-agent
v0.7.7 — 模块拆分收口
Study Agent v0.7.7 release notes
模块拆分收口版。wechat.py 从 ~1243 行拆为 6 个独立模块,保留兼容层,无功能变更。
1. 模块拆分总览
旧 src/wechat.py(~1243 行)拆为 6 个文件:
| 模块 | 职责 | 行数 |
|---|---|---|
src/wechat.py |
兼容层 + 群聊生命周期、互动回复、开场生成、搜索摘要 | ~540 |
src/wechat_format.py |
纯文本/格式化工具(角色块解析、兜底文案) | ~95 |
src/news/link_resolver.py |
Google News 跳转链接解析 | ~90 |
src/news/article_fetcher.py |
正文抓取 + DNS/IP 安全校验 | ~180 |
src/news/rss_fetcher.py |
RSS 多源抓取 + 去重 + 排序 + 缓存 | ~280 |
src/news/digest.py |
摘要生成 + 来源块格式化 | ~150 |
2. src.wechat 仍作为兼容层
from src.wechat import fetch_news_items等依然可用- 所有对外接口通过
# noqa: F401re-export 保持向后兼容 wechat_service.py等上层调用方无需修改
3. RSS 阶段不再逐条 resolve 链接
_fetch_rss_items_from_url()中resolved_link = ""fetch_news_items(query_text, max_items, resolve_top_n=5):- 多源拉取(Google News / Bing News / RSSHub 国内源)
- 排序 → 去重 → 截断
- 仅对存活条目中前
resolve_top_n条执行resolve_news_link()
- 新增
resolve_top_n参数,便于测试中断言调用次数
4. 后续计划(本轮暂停)
wechat_store:群聊文件 I/O、state 管理、archivewechat_generation:opening、interactive reply、digest discussion- 以上暂缓拆分,先稳定当前拆分点
兼容性
- 无新增依赖
- 所有 107 项测试通过
test_resolve_news_link_called_only_after_dedup保证 resolve 次数 ≤ resolve_top_n.claude/已加入.gitignore
v0.7.6
工程安全与新闻链路收口
- 加固 .gitignore 与打包排除规则 — 新增
.env.*、*.env等模式 - 修复侧栏 HTML 转义 —
_section()/_mini_state()增加html.escape() - 重构新闻抓取链路 — RSS 阶段不再 resolve 链接,先 dedupe/trim 再 resolve
- 补强 URL 安全边界 — 新增
_check_dns_target_safe()DNS/IP 安全校验 - 修正测试与增强 CI — 修正无效 monkeypatch、新增 package helper / detect-secrets / expanded mypy
详见 changelog/README_v0_7_6.md
v0.7.5
文档同步收口 + 代码清理 + 修复优化
- 版本同步收口 — 10 个 memory/doc 文件补齐 v0.7.4/v0.7.5 版本字段
- 死代码清理 — 删除
chat_stream()、重复_file_signature()、重复CONTEXT_FILE_GROUPS/MEMORY_SELECTION - YAML 同步 I/O 优化 — mtime canary 避免每次
load_runtime_modes()冗余读取 - 重复逻辑合并 —
_display_*函数合并、st.rerun()fallback 去重、缓存清理函数合并 - 108 tests passing, ruff check clean
详见 changelog/README_v0_7_5.md
v0.7.4
工程体验收口
- 自动化版本 bump 工具 —
tools/bump_version.py,一次命令同步 7 个文件 - LLM 客户端配置文档化 —
.env.example扩展至 50 行,覆盖 5 个 provider - NewsRoundResult 结果对象化 — source_block / article_coverage / elapsed_ms / warnings 结构化输出
- UI 来源可信度展示 — 覆盖率条、警告逐条展示、📄/📰 条目图标区分
- 108 tests passing, ruff check clean
详见 changelog/README_v0_7_4.md
v0.7.3
v0.7.2 — 代码质量全面收口
Study Agent v0.7.2 代码质量收口说明
当前版本仍属于自用检查包,不是正式对外发布版。
本阶段重点是对项目做全量代码扫描与优化收口,修复已有 Bug,改善性能和架构。
1. 当前阶段定位
v0.7.2 是在 v0.7.1 基础上的代码质量收口版,重点不在功能增量,而是:
- 修复已发现的 4 个 Bug(含 1 个测试失败、2 个 stale 数据、1 个统计错误)
- 性能优化(缓存落盘重复读取、YAML 重复解析、diff 算法)
- 架构改善(常量去重、代码栅栏清理抽公共、文章提取模块独立)
- Streamlit 反模式修复(fragment 内完整 rerun → scope=fragment)
- 错误处理增强(关键路径裸 except 加日志、after_session 崩溃保护)
- 依赖清理
2. 本阶段关键变化
2.1 Bug 修复(P0)
- 测试版本断言 stale:
test_runtime_version_is_synced_to_v069断言v0.6.9,实际已是v0.7.1,改名为test_runtime_version_is_synced并更新断言值 - 欢迎页硬编码版本:
chat_panel.py:131写死v0.6.2 响应速度优化,改为load_runtime_modes().current_version动态读取 - LLM Router 用量统计:
model_stats.py:109无论用 flash 还是 pro 都记录为 flash,修复为接收model_profile参数 - 死代码删除:
src/ui/main_panel.py从未被调用,已删除
2.2 性能优化(P1)
load_runtime_modes()缓存:src/mode_manager.py加@st.cache_data(ttl=30),同一渲染周期内只读一次文件(之前每次渲染被调用 5+ 次)- YAML 路由重复解析:
router.py中load_routing_config()读一次 YAML,_match()又读一次。修复为_match()接受预加载 rules 参数,避免重复 I/O - diff 算法优化:
memory_tools.pydiff 从 O(n×m) 嵌套循环改为 set 集合运算
2.3 架构改善(P1)
- 公共常量抽取:
ROLE_LABELS/MODE_LABELS/MODEL_LABELS等原本在sidebar.py/status_bar.py/chat_panel.py/wechat_panel.py四份文件中重复定义,统一到src/constants.py - 代码栅栏清理工具:
strip_code_fences()原本在llm_router.py/after_session.py/wechat_memory.py三处重复实现,抽取到src/text_utils.py - 文章提取模块独立:
wechat.py中ArticleTextExtractor类及_extract_article_text_*系列函数迁移到src/news/article_extractor.py,wechat.py保留向后兼容的 re-export
2.4 Streamlit 反模式修复(P1)
- wechat_panel fragment 内 rerun:
wechat_panel.py中 8 处st.rerun()改为st.rerun(scope="fragment"),避免完整页面重刷 - sidebar fragment 内 rerun:
sidebar.py中 6 处st.rerun()改为st.rerun(scope="fragment")
2.5 错误处理增强(P2)
- 公共日志模块:新建
src/log_utils.py,统一logging.getLogger("study_agent") after_session.py崩溃保护:LLM 调用加 try/except,失败时返回友好提示而非崩溃- 关键路径日志:
router.py(YAML 加载失败、LLM 路由失败)、llm_router.py(chat 失败、JSON 解析失败)、config.py(reload 失败)均从静默吞异常改为 WARNING 日志
2.6 依赖清理(P2)
requirements.txt移除pytest>=8.0,<9(应只在requirements-dev.txt中)
3. 新增文件清单
| 文件 | 用途 |
|---|---|
src/constants.py |
公共常量字典(ROLE/MODE/MODEL/PERF/ATMOS/ENTRY/WECHAT labels & icons) |
src/text_utils.py |
文本工具(strip_code_fences) |
src/log_utils.py |
公共日志 logger |
src/news/__init__.py |
news 子包 |
src/news/article_extractor.py |
文章正文提取(HTMLParser + trafilatura + readability 三层回退) |
| 删除文件 | 原因 |
|---|---|
src/ui/main_panel.py |
死代码,从未被调用 |
4. 建议检查命令
python -m compileall -q .
python -m pytest -q
streamlit run app.py5. 测试结果
本次改动后全量测试:72 passed, 0 failed。
v0.7.1
v0.7.1(含 v0.7.0 基础)
v0.7.0:
- 联网检索多源聚合(Google / Bing / RSSHub)
- 正文三层提取链路:trafilatura → readability-lxml → HTMLParser
- 正文读取失败不中断整轮群聊
- 搜索来源块写入群聊记录
- 摘要 prompt 增加事实边界约束
- URL 安全检查:拦截 localhost/私有地址
v0.7.1 新增收口(2026-05-09):
版本身份统一:
- 消除三套版本号并存(包名 v0.6.9 / 计划 v0.7.0 / memory v0.7.1)
src/mode_manager.py→ v0.7.1 / v0.7.2(next)- 所有 memory/ 文档、PROJECT_PLAN、USER_GUIDE、COMPREHENSIVE_PROJECT、FUTURE、README_internal_modes、README.md 统一为 v0.7.1
memory/current_focus.md新增版本同步文件清单(13 个文件),后续改版本号对照即可
.env.example 与 USER_GUIDE.md 配置对齐:
- 统一为 deepseek-v4-flash / deepseek-v4-pro / pro / /v1
- 明确
.env.example是唯一准配置,USER_GUIDE 仅做镜像引用
_article_fetch_priority 泛化:
- 移除写死的 OpenAI / 语音 / audio 专题关键词
- 改为通用五维优先级:中转链接降权 + 官方域名加权 + 可信媒体加权 + 标题匹配 query + 近期优先
query_text透传到排序函数,搜 Godot 不会偏到音频关键词- 新增测试
test_article_fetch_priority_uses_generic_query_matching_for_non_openai_queries
搜索结果:
- 默认优先近 90 天结果
- 来源块压缩为短格式(标题 + 域名 + 正文状态)
- 摘要 prompt 显式告知正文覆盖率
- 侧栏状态与 memory 同步到 v0.7.1
修复:
- digest prompt 乱码
- 链接域名压缩、覆盖状态对齐
v0.6.9
v0.6.9
- 新增联网查点什么自由文本搜索,支持任意主题 / New free-text search for any topic via Google News
- fetch_news_items(query_text, max_items) 替代硬编码查询 / fetch_news_items replaces hardcoded query
- 新闻缓存重构为按查询键值的字典 / News cache refactored to dict keyed by query
- _run_news_round() 支持可选 query_text 参数,完全向后兼容 / _run_news_round() optional query_text, backward-compatible
- 搜索/慢操作显示分阶段进度指示 / Staged progress indicators for slow operations
- exports/ 目录加入打包排除 / exports/ added to packaging exclusions
- session_logger.save 走 safe_write_text / session_logger via safe_write_text
v0.6.8
v0.6.8(含 v0.6.7)
v0.6.7:
- 微信群刷新拆分为局部/全局两种方式 / WeChat refresh split into local fragment and global app rerun
- 新增 notice queue 避免成功提示一闪消失 / Notice queue prevents success messages vanishing on rerun
- 开场氛围切换改为点击后生效 / Mood switch now takes effect on click, not on change
- 健康检查不再主动创建运行时目录 / Health check no longer creates runtime directories
- 打包排除规则大小写不敏感 + 排除 .docx / Case-insensitive exclusions + exclude .docx
- 新闻按钮增加分阶段提示 / News button added staged progress indicators
- 群聊文件读取和气泡渲染增加缓存 / File read and bubble render cached with lru_cache
- safe_writer 增加 Windows 文件锁重试 / safe_writer adds Windows file-lock retry
v0.6.8:
- .tmp 文件排除在打包输出之外 / .tmp files excluded from packaging
- safe_writer 加入 finally 清理 / finally-block cleanup for temp files
- LLM client 配置变更时自动重建 / Auto-rebuild on config reload
- wechat_state 多字段更新合并为单次写入 / Multi-field updates batched into single write
- 侧边栏查看未读自动切到微信群 / View unread auto-switches to WeChat entry
- 健康检查可写判断改进 / Writability detection improved
- 新闻 RSS 加入 10 分钟缓存 / News RSS 10-minute cache
v0.6.6
v0.6.6(含 v0.6.5)
v0.6.5:
- 微信群开场改为用户先选氛围再生成 / Opening requires selecting mood first, then generates
- 开场 prompt 禁止角色提前知道用户会来 / Opening prompt forbids characters knowing user will arrive
- 四角色群聊增加最终归一化兜底 / Added final normalization to ensure all 4 characters speak
- 旧版错误开场自动识别并重生成 / Broken old openings auto-detected and regenerated
- 左侧状态与 memory 文档彻底对齐 / Sidebar status synced with memory documents
- 打包脚本拆分为 ps1 + helper.py / Package script split into ps1 + helper.py
v0.6.6:
- 未知发言人不再 fallback 为 user,渲染为 system-bubble / Unknown speakers rendered as system-bubble
- safe_writer 临时文件加唯一时间戳防并发 / Temp files uniquely timestamped against race conditions
- 打包守护测试对齐当前结构 / Packaging guard tests aligned to current structure