Skip to content

Releases: 2002yy/study-agent

v0.7.7 — 模块拆分收口

16 May 14:15

Choose a tag to compare

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: F401 re-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)
    1. 多源拉取(Google News / Bing News / RSSHub 国内源)
    2. 排序 → 去重 → 截断
    3. 仅对存活条目中前 resolve_top_n 条执行 resolve_news_link()
  • 新增 resolve_top_n 参数,便于测试中断言调用次数

4. 后续计划(本轮暂停)

  • wechat_store:群聊文件 I/O、state 管理、archive
  • wechat_generation:opening、interactive reply、digest discussion
  • 以上暂缓拆分,先稳定当前拆分点

兼容性

  • 无新增依赖
  • 所有 107 项测试通过
  • test_resolve_news_link_called_only_after_dedup 保证 resolve 次数 ≤ resolve_top_n
  • .claude/ 已加入 .gitignore

v0.7.6

16 May 12:24
7139b11

Choose a tag to compare

工程安全与新闻链路收口

  1. 加固 .gitignore 与打包排除规则 — 新增 .env.**.env 等模式
  2. 修复侧栏 HTML 转义_section() / _mini_state() 增加 html.escape()
  3. 重构新闻抓取链路 — RSS 阶段不再 resolve 链接,先 dedupe/trim 再 resolve
  4. 补强 URL 安全边界 — 新增 _check_dns_target_safe() DNS/IP 安全校验
  5. 修正测试与增强 CI — 修正无效 monkeypatch、新增 package helper / detect-secrets / expanded mypy

详见 changelog/README_v0_7_6.md

v0.7.5

16 May 11:43
d8cffe0

Choose a tag to compare

文档同步收口 + 代码清理 + 修复优化

  1. 版本同步收口 — 10 个 memory/doc 文件补齐 v0.7.4/v0.7.5 版本字段
  2. 死代码清理 — 删除 chat_stream()、重复 _file_signature()、重复 CONTEXT_FILE_GROUPS/MEMORY_SELECTION
  3. YAML 同步 I/O 优化 — mtime canary 避免每次 load_runtime_modes() 冗余读取
  4. 重复逻辑合并_display_* 函数合并、st.rerun() fallback 去重、缓存清理函数合并
  5. 108 tests passing, ruff check clean

详见 changelog/README_v0_7_5.md

v0.7.4

16 May 11:43
d8cffe0

Choose a tag to compare

工程体验收口

  1. 自动化版本 bump 工具tools/bump_version.py,一次命令同步 7 个文件
  2. LLM 客户端配置文档化.env.example 扩展至 50 行,覆盖 5 个 provider
  3. NewsRoundResult 结果对象化 — source_block / article_coverage / elapsed_ms / warnings 结构化输出
  4. UI 来源可信度展示 — 覆盖率条、警告逐条展示、📄/📰 条目图标区分
  5. 108 tests passing, ruff check clean

详见 changelog/README_v0_7_4.md

v0.7.3

16 May 11:43
d8cffe0

Choose a tag to compare

服务层拆分与工程化收口

v0.7.2 — 代码质量全面收口

16 May 07:38

Choose a tag to compare

Study Agent v0.7.2 代码质量收口说明

当前版本仍属于自用检查包,不是正式对外发布版。
本阶段重点是对项目做全量代码扫描与优化收口,修复已有 Bug,改善性能和架构。


1. 当前阶段定位

v0.7.2 是在 v0.7.1 基础上的代码质量收口版,重点不在功能增量,而是:

  1. 修复已发现的 4 个 Bug(含 1 个测试失败、2 个 stale 数据、1 个统计错误)
  2. 性能优化(缓存落盘重复读取、YAML 重复解析、diff 算法)
  3. 架构改善(常量去重、代码栅栏清理抽公共、文章提取模块独立)
  4. Streamlit 反模式修复(fragment 内完整 rerun → scope=fragment)
  5. 错误处理增强(关键路径裸 except 加日志、after_session 崩溃保护)
  6. 依赖清理

2. 本阶段关键变化

2.1 Bug 修复(P0)

  • 测试版本断言 staletest_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.pyload_routing_config() 读一次 YAML,_match() 又读一次。修复为 _match() 接受预加载 rules 参数,避免重复 I/O
  • diff 算法优化memory_tools.py diff 从 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.pyArticleTextExtractor 类及 _extract_article_text_* 系列函数迁移到 src/news/article_extractor.pywechat.py 保留向后兼容的 re-export

2.4 Streamlit 反模式修复(P1)

  • wechat_panel fragment 内 rerunwechat_panel.py 中 8 处 st.rerun() 改为 st.rerun(scope="fragment"),避免完整页面重刷
  • sidebar fragment 内 rerunsidebar.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.py

5. 测试结果

本次改动后全量测试:72 passed, 0 failed

v0.7.1

09 May 03:21

Choose a tag to compare

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.exampleUSER_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

09 May 03:30

Choose a tag to compare

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

09 May 03:21

Choose a tag to compare

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

09 May 03:21

Choose a tag to compare

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