Repository navigation
Conversation
CATMIAOZHI
left a comment
There was a problem hiding this comment.
审计结论:❌ 请求修改
改动(42 文件,+2203/−1023):上下文总结配置从 ModelConfigData 解绑,改由角色卡 summary 字段与全局默认持有;设置界面、提示词读取、触发阈值经 SummarySettingsResolver 同源解析;修复分段关闭被后续编辑带回、全关变自相矛盾空壳、自定义规则被当成待总结内容、插入总结丢失 previousSummary 四处失效;AI 消息纳入总结范围。
通过的检查:
- 目标分支
dev正确 SummarySettingsResolver纯函数,单测覆盖 CUSTOM / FOLLOW_GLOBAL / 未知模式回退 / 群聊- 删除角色卡时
getCharacterCardFlow回退为合成默认卡 → FOLLOW_GLOBAL → 全局配置,无崩溃,摘要归属正确 - DataStore 新增
character_card_${id}_summary_binding_mode/summary_json键;删卡时清理;JSON 解析失败回退默认并打日志 - 分段覆盖改为规范化全量持久化且
enabled恒写入,修掉"关闭分段被带回";全关走自由格式指令;自定义规则加指令头 - 插入总结与自动总结并入同一链路,复用
_isSummarizing并发保护,autoContinue=false不会让模型续写回复 - 设置界面自动保存收敛为单个 effect(防抖 700ms + 完整对象一次性写入),消除旧多 effect 用旧快照互相覆盖
- 旧
ModelConfigDataJSON 因ignoreUnknownKeys=true不会解析失败 - PR 描述与 diff 一致;作者已验证编译通过与三个单测套件通过
问题:
- [major] 存量自定义总结设置无迁移、静默丢失:旧
ModelConfigData上的 summary 自定义(阈值/规则/分段/对话回顾)随字段删除被丢弃。默认值一致所以默认用户无感,但自定义过的用户升级后配置丢失且无提示。"不需要预迁移"的结论只对默认用户成立。建议加一次迁移(把旧全局 CHAT 模型配置的 summary 设置搬到global_context_summary_settings),或 maintainer 明确接受并写进更新说明。 - [minor]
updateActiveSummarySettings有 read-modify-write 竞态:configScope.launch内先读 activePrompt 再读卡再写,切换角色卡的瞬间写入可能落到旧卡上;updateCharacterCardSummarySettings的 get-then-update 也非原子。UI 侧已收敛为单一写入入口,实际触发概率低,建议写入前复核 activePrompt 是否变化。 - [minor] 新代码
catch (e: Exception)吞掉CancellationException:SummarySettingsAutoSaveEffect里onSave的 catch(已挂行内);readSummaryConfig/loadRuntimeChatMessagesForSummaryInsertion沿用旧模式。建议统一先 rethrowCancellationException。 - [minor/question]
XaiProviderReasoningTest直接删掉 3 个测试而不是修复:与本 PR 无关的覆盖丢失,建议拆独立 PR 处理或在描述里说明删除原因。 - [nit] 插入总结窗口从会话起点无界加载(保留 summary 消息以还原 previousSummary 是对的),超长会话长按靠后消息时全量 hydrate 内存占用大;建议评估加个合理上限。
后续可跟进(不阻塞):无。
改完第 1 条(加迁移或确认接受不迁移)后可再审,其余为建议项。
| * FOLLOW_GLOBAL 时,运行时统一解析到这份配置。缺失或损坏时回退默认值, | ||
| * 保证与迁移前的默认行为一致。 | ||
| */ | ||
| val globalContextSummaryFlow: Flow<ContextSummarySettings> = |
There was a problem hiding this comment.
[major] 旧全局 CHAT 模型配置上的 summary 自定义(阈值/规则/分段/对话回顾)在此丢失且无迁移:默认值一致只保证默认用户无感。建议加一次迁移,把旧配置的 summary 字段搬到这里;或 maintainer 明确接受并写进更新说明。
| ) | ||
| onSave(settings) | ||
| onSummaryErrorChange(null) | ||
| } catch (e: Exception) { |
There was a problem hiding this comment.
[minor] catch (e: Exception) 会吞掉 CancellationException(collectLatest 取消上一轮时抛出的正是它),可能导致快速连续输入时误报"保存失败"。建议先 catch (e: CancellationException) { throw e }。
|
CATMIAOZHI
left a comment
There was a problem hiding this comment.
复审结论:✅ 通过(针对新提交 f290a7e 的复审)
上次 review(commit 68611de,REQUEST_CHANGES)提出 5 个问题,作者在新提交 f290a7ef 中全部处理完毕并逐条回复。本轮只审新增 diff(13 文件,+520/−23),未重新审计全量。
核验结果(逐条):
-
[major] 存量总结配置迁移 — 已修复:新增
ContextSummarySettingsMigration,读旧全局 CHAT 模型配置的原始 JSON(而不是解析成已删字段的ModelConfigData,否则解析即丢数据)映射 8 个字段到global_context_summary_settings。我逐项核对了LegacySummaryFields的默认值的与旧ModelConfigData完全一致(DEFAULT_ENABLE_SUMMARY=true、DEFAULT_SUMMARY_TOKEN_THRESHOLD=0.70f、DEFAULT_ENABLE_SUMMARY_BY_MESSAGE_COUNT=true、DEFAULT_SUMMARY_MESSAGE_COUNT_THRESHOLD=16、enableSummaryDialogueReview=true、summaryDialogueReviewTitle=""、summaryCustomRules=""、summarySectionOverrides=[]),保证只迁移真实自定义值。完成标记context_summary_migrated_from_model_config落在 user_preferences + 进程内 Mutex 双重保证只执行一次,解析失败/源缺失只记日志不覆盖全局默认。globalContextSummaryFlow改为flow { ensureMigrated; emitAll(...) },eager 消费者在迁移完成前不会读到旧默认值。ContextSummarySettingsMigrationTest7 个用例覆盖全量字段映射、旧对话回顾字段名、缺字段回退、损坏 JSON 不迁移。角色卡 FIXED_CONFIG 差异不保留已在 PR 描述明确说明,可接受。 -
[minor] updateActiveSummarySettings 读写竞态 — 已修复:抽出
resolveActiveSummaryCard(),写入前再解析一次并比对卡 id,不一致则AppLogger.w记日志并放弃本次写入。updateCharacterCardSummarySettings的 get-then-update 未改动,作者在回复中已如实说明;UI 侧已收敛为单一写入入口,残余窗口极窄,可接受。 -
[minor] catch 吞 CancellationException — 已修复:三处都补了
catch (e: CancellationException) { throw e }——SummarySettingsAutoSaveEffect.onSave(注释说明 collectLatest 取消不是保存失败,快速连续输入不再误报)、MessageCoordinationDelegate.readSummaryConfig、ChatHistoryManager.loadRuntimeChatMessagesForSummaryInsertion。 -
[minor/question] 删除 XaiProviderReasoningTest 的 3 个测试 — 已说明:PR 描述新增"关于删除 XaiProviderReasoningTest 的 3 个测试"一节,说明引用的三个符号在仓库与 dev tip 上均不存在、同类覆盖由
OpenAiChatReasoningEffortTest与ThinkingQualityMappingTest承担;DeepseekProviderMediaRoleTest的反射写法与上游既有写法一致。符合上次建议的"在描述里说明删除原因"。 -
[nit] 插入总结无界装载 — 已修复:新增
getLatestSummaryTimestampUpTo(MessageDao 层,sender='summary' AND timestamp<=查询),窗口下界锚到目标消息之前最近一条 summary(含该条),previousSummary仍能还原;未加条数上限的理由(上限会连 summary 之后的内容一起丢掉)成立且已写进注释。
新增 diff 中的新问题:无。只有一个极小的 [nit]:ContextSummarySettingsMigration.kt 文件末尾缺少换行符,可顺手补上。
作者评论(2026-09-26T03:35:43Z)逐条回应了上次 review 的 5 点,与代码实现一致,无需额外讨论。
本轮无阻塞项,5 个问题全部闭环,建议合并。
由 水晴喵的muse 审计
- 上下文总结配置从 ModelConfigData 迁出,改由角色卡与全局默认持有,设置界面、提示词读取、触发阈值三条链路统一经 SummarySettingsResolver 解析 - 分段覆盖改为规范化全量持久化,enabled 恒写入,避免关闭分段被后续编辑带回 - 关闭全部分段时不再输出与空正文矛盾的格式要求清单,改为可执行的自由格式总结指令;部分关闭时追加分段锁定约束,禁止模型补回未列出的分段 - 自定义总结规则改为带指令头的段落,不再裸拼在提示词末尾被模型当作待总结内容 - 插入总结与自动总结合入同一条链路,装载窗口保留 summary 消息以还原 previousSummary,写入不再经过模型配置 - 把 AI 消息纳入待总结范围:只总结用户消息会让摘要退化成问题清单,丢失结论、代码片段与工具调用结果;纳入 assistant 消息后,压缩出的历史自带任务产出,无需回溯原文即可继续对话 - 清理 ModelConfigData、ModelConfigResultItem、SUMMARY 工具参数与 MessageDao 查询中的总结字段
…e paths - 存量总结设置挂在模型配置上,字段已从 ModelConfigData 删除,改为一次性迁移到全局默认总结配置:直接读旧配置的原始 JSON 解析 8 个字段,完成标记落在 user_preferences 保证只执行一次,源配置缺失或解析失败只记日志不覆盖全局默认 - globalContextSummaryFlow 迁移先于读取,避免 eager 消费者在迁移完成前读到迁移前的默认值 - updateActiveSummarySettings 写入前重新解析并比对生效目标,切换角色卡瞬间的编辑不再落到另一张卡上 - 三处 catch 透传 CancellationException,快速连续输入不再因 collectLatest 取消而误报保存失败 - 插入总结装载窗口锚到目标消息之前最近一条 summary,长会话不再从会话起点无界 hydrate,previousSummary 仍能还原
f290a7e to
9d83f48
Compare
|
已把本 PR 的分支 rebase 到最新
验证: |
CATMIAOZHI
left a comment
There was a problem hiding this comment.
复审结论:✅ 通过(针对 rebase 后新 head 9d83f48 的复审)
head 由 f290a7ef 变为 9d83f486,是作者 2026-11-13 把分支 rebase 到最新 dev 后的 force-push(此前与 dev 冲突),并非新增功能提交;作者同日评论说明了分歧处理方式。本轮只审 rebase 带来的变化,未重新审计全量。
核验方法:分别取旧版 PR diff(旧 base dbf71916..f290a7ef,46 文件 +2700/−1023)与新版 PR diff(新 base aeb569bf..9d83f486,44 文件 +2685/−988)逐项比对。
核验结果:
- 44 个共有文件的 PR diff 内容逐字节一致,仅 hunk 行号随
dev漂移而变。已批准的全部改动原样保留:ContextSummarySettingsMigration(8 字段一次性迁移)、resolveActiveSummaryCard写入前复核、getLatestSummaryTimestampUpTo窗口下界锚定均在新 head 中;三处CancellationException重抛(SummarySettingsAutoSaveEffect、readSummaryConfig、loadRuntimeChatMessagesForSummaryInsertion)也已抽查确认仍在。 - 仅有的两处内容差异与作者说明一致,均为冲突处理时采用
dev现状:DeepseekProviderMediaRoleTest.kt:放弃本地反射改写,采用dev上的createRequestBodyForTest辅助;新 head 中该文件存在且调用 dev 的辅助方法,无 PR 自身改动残留。XaiProviderReasoningTest.kt:dev上不存在该文件,保持不存在;旧 diff 中删除 3 个失效测试的改动随之消失(删除对象已不存在,无覆盖丢失)。
- 上轮 [nit] 已顺手补上:
ContextSummarySettingsMigration.kt新 head 中以换行符结尾。 - 作者称
./gradlew :app:compileDebugKotlin -x :app:syncSttModelAssets通过,单元测试交由 CI;截至复审时该 commit 尚未上报 CI 检查结果,合并前请确认 CI 通过。
本轮 rebase 干净,无新增问题,建议合并(待 CI 通过)。
由 水晴喵的muse 审计
变更说明 / Description
把上下文总结的配置从模型配置上解绑,改由角色卡与全局默认持有,并让设置界面、提示词读取、触发阈值三条链路解析同一份配置。顺带修掉三处用户可见的失效:关闭分段被后续编辑带回、关闭全部分段后提示词变成自相矛盾的空壳、插入总结丢失上一次摘要。
背景与动机 / Context and motivation
总结配置此前挂在
ModelConfigData上,实际跟着模型而非角色卡走;且设置界面固定读全局 CHAT 映射的模型配置,触发阈值走effectiveChatConfigId,角色卡固定对话模型时界面改动在运行时被忽略,切换角色卡也不改变总结行为。用户报告的具体失效包括:关闭所有板块开关并设置自定义规则后,生成的总结仍是默认多板块格式,自定义规则被当作待总结内容;长按消息插入总结时只输出规则文本,没有总结正文。改动范围 / Changes
ContextSummarySettings聚合与SummarySettingsResolver,总结配置改由角色卡summary字段与全局默认共同持有;界面、运行时提示词、触发阈值经resolveSummarySettings()同源解析enabled恒写入,关闭分段不再被后续编辑悄悄带回summarizeHistory与readSummaryConfig,装载窗口保留 summary 消息以还原previousSummary,写入不再经过模型配置ModelConfigData、ModelConfigResultItem、SUMMARY 工具参数与MessageDao查询中的总结字段,删除随之失去引用的装载方法docs/TODO/context_summary_character_card_binding_20260923/八个步骤记录与架构说明不包含:总结所用模型仍走全局
FunctionType.SUMMARY映射,未改变;本次提交不含本地构建环境所需的 Gradle/AGP 版本适配改动。为什么把 AI 消息纳入总结
只把用户消息送进总结,摘要会退化成一串问题清单:模型看得到"用户问过什么",看不到"AI 答过什么、做过什么、改过什么"。任务结论、代码片段、工具调用结果全部丢失,压缩后的历史无法自包含,后续对话只能反复回溯原始记录才能继续。
把 assistant 消息一并纳入后,总结记录的是完整交互:用户的意图,加上 AI 给出的方案、结论与产出。上下文被压缩时任务状态和实际成果一起被保留,模型不回读原文也能接上进度。为保证这部分输入不膨胀,assistant 消息在送入前经过
removeThinkingContent剥离思考过程、stripMediaLinksForAssistant剥离媒体占位、condenseAssistantForReview压缩超长输出,只保留实质内容;群聊场景下 AI 消息带roleName,可按角色归属还原多方结论。兼容性与风险 / Compatibility and risks
summaryBindingMode与summary_json两个 DataStore 键,全局新增global_context_summary_settings键。缺失或 JSON 解析失败时回退ContextSummarySettings(),与迁移前的默认行为一致,不需要预迁移FOLLOW_GLOBAL、群聊会话或没有角色卡时使用全局默认配置;已删除的模型配置 summary 字段随本次变更一并清理,ModelConfigResultItem相关字段移除关联 Issue / Related issue
N/A。来自本地测试中发现的总结配置失效与插入总结内容缺失,未在仓库创建对应 Issue。
验证方式 / Verification
检查或命令:
./gradlew :app:compileDebugKotlin
./gradlew :app:testDebugUnitTest --tests "com.ai.assistance.operit.core.config.FunctionalPromptsSummaryTest"
./gradlew :app:testDebugUnitTest --tests "com.ai.assistance.operit.data.model.ContextSummarySettingsTest"
./gradlew :app:testDebugUnitTest --tests "com.ai.assistance.operit.data.model.SummarySettingsResolverTest"
环境与变体:Windows 11,JDK 21,Android SDK 36,NDK 28.2.13676358,debug 变体
结果:
证据 / Evidence
提示词渲染的前后对比可由单测直接断言:关闭全部分段后提示词不再包含任一
【】分段标题与"必须使用上述固定格式"清单,改为自由格式指令;未编辑用户首次落盘后生成的提示词与默认模板逐字一致。检查清单 / Checklist
dev;如目标为main,我已说明这是维护者发布同步 / The target branch isdevfor regular work; if it ismain, I explained why this is a maintainer-led release syncCandidate checks覆盖改动范围,并会处理技术失败项 /Candidate checkscovers the change scope and technical failures will be addressed存量 summary 配置迁移
改动前总结配置(token 阈值、自定义规则、分段覆盖、对话回顾)挂在 ModelConfigData 上,本 PR 把这些字段删除并改为角色卡 + 全局默认持有。自定义过这些配置的存量用户升级后不应静默回到默认值,因此加了一次性迁移:
关于删除 XaiProviderReasoningTest 的 3 个测试
该文件引用的 XaiReasoningMapper / effortForOption / xaiModelSupportsReasoningEffort 三个符号在仓库与 dev tip 上均不存在,是上游 thinking-controls 重构后遗留的失效测试,无法编译;同类 effort 映射行为现由 OpenAiChatReasoningEffortTest 与 ThinkingQualityMappingTest 覆盖。为让本分支可编译,删除了这 3 个测试,未改动其他测试。DeepseekProviderMediaRoleTest 改为反射调用 createRequestBody(protected,测试类非子类),与上游对 DeepSeek 路径的既有写法一致。