feat: Implement context compression and summary#4581
Conversation
|
""" Walkthrough本次变更为聊天相关核心模块引入了“特性注册表”(ChatFeatureRegistry)依赖,实现了聊天模型与消息历史管理的依赖注入,并扩展了消息历史的内存压缩、工具调用追踪和摘要能力。部分组件实现了更细致的消息摘要与异步标题更新逻辑,同时相关类型接口也做了相应增强。测试代码同步适配了依赖注入方式。 Changes
Sequence Diagram(s)sequenceDiagram
participant UI
participant ChatManagerService
participant ChatModel
participant MsgHistoryManager
participant ChatFeatureRegistry
participant IMessageSummaryProvider
UI->>ChatManagerService: startSession()/fromJSON()
ChatManagerService->>ChatFeatureRegistry: 获取实例(依赖注入)
ChatManagerService->>ChatModel: new ChatModel(ChatFeatureRegistry, ...)
ChatModel->>MsgHistoryManager: new MsgHistoryManager(ChatFeatureRegistry, ...)
MsgHistoryManager->>ChatFeatureRegistry: 调用摘要/工具调用等特性
ChatModel->>MsgHistoryManager: getMessageHistory()
MsgHistoryManager->>IMessageSummaryProvider: generateMemorizedMessage()
MsgHistoryManager-->>ChatModel: 返回消息历史(含摘要/工具调用信息)
ChatModel-->>ChatManagerService: 返回会话模型
ChatManagerService-->>UI: 返回会话
Possibly related PRs
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
yarn install v1.22.22 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (4)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
/next |
|
🎉 PR Next publish successful! 3.9.1-next-1749007675.0 |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
packages/startup/entry/sample-modules/ai-native/ai-native.contribution.ts (1)
61-63: 消息摘要功能实现良好实现了智能的缓存机制,避免了频繁的 API 调用。错误处理得当,在失败时能够返回缓存的摘要。提示词结构清晰,包含了好坏示例。
建议将更新阈值设为可配置项:
-private readonly SUMMARY_UPDATE_THRESHOLD = 10; // 每10条消息更新一次摘要 +private SUMMARY_UPDATE_THRESHOLD = 10; // 每10条消息更新一次摘要 + +// 在某处添加配置方法 +public setSummaryUpdateThreshold(threshold: number): void { + this.SUMMARY_UPDATE_THRESHOLD = threshold; +}这样可以根据不同场景调整摘要更新频率。
Also applies to: 244-285
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
8-32: 内存分层管理设计优秀三层内存管理系统(短期、中期、长期)的设计很有创意,能够有效平衡内存使用和历史信息保留。对工具调用信息的分层处理也很合理。
建议在实际使用中监控以下指标以优化配置:
- 各层内存的命中率
- 摘要生成的耗时和成功率
- 用户对历史信息召回的满意度
这些数据可以帮助调整默认的窗口大小(10/20/50)以获得最佳性能。
Also applies to: 45-49, 95-198
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/ai-native/src/browser/chat/chat-manager.service.ts(3 hunks)packages/ai-native/src/browser/chat/chat-model.ts(5 hunks)packages/ai-native/src/browser/chat/chat.feature.registry.ts(3 hunks)packages/ai-native/src/browser/chat/chat.view.tsx(2 hunks)packages/ai-native/src/browser/model/msg-history-manager.ts(8 hunks)packages/ai-native/src/browser/types.ts(3 hunks)packages/extension/__tests__/browser/extension-service/extension.service.test.ts(0 hunks)packages/startup/entry/sample-modules/ai-native/ai-native.contribution.ts(3 hunks)
💤 Files with no reviewable changes (1)
- packages/extension/tests/browser/extension-service/extension.service.test.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
packages/ai-native/src/browser/chat/chat.feature.registry.ts (1)
packages/ai-native/src/browser/types.ts (1)
IMessageSummaryProvider(304-311)
packages/ai-native/src/browser/chat/chat-model.ts (1)
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
MsgHistoryManager(33-353)
packages/ai-native/src/browser/chat/chat.view.tsx (3)
packages/core-browser/src/react-hooks/injectable-hooks.tsx (1)
useInjectable(16-39)packages/core-common/src/types/ai-native/index.ts (1)
ChatFeatureRegistryToken(297-297)packages/ai-native/src/common/utils.ts (1)
cleanAttachedTextWrapper(63-69)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: 🚀🚀🚀 Next Version for pull request
- GitHub Check: build (macos-latest, 20.x)
- GitHub Check: build (ubuntu-latest, 20.x)
- GitHub Check: ubuntu-latest, Node.js 20.x
- GitHub Check: build-windows
🔇 Additional comments (11)
packages/ai-native/src/browser/types.ts (3)
8-8: 导入添加合理正确导入了
ChatMessageRole类型,用于新的消息摘要接口定义。
139-139: 接口扩展恰当在
IChatFeatureRegistry接口中添加registerMessageSummaryProvider方法,与现有的注册模式保持一致。
304-311: 接口设计良好
IMessageSummaryProvider接口设计简洁明了:
- 使用
Promise<string | undefined>支持异步操作和可选结果- 参数类型明确,包含角色和内容信息
- 方法命名具有描述性
符合现有代码风格和最佳实践。
packages/ai-native/src/browser/chat/chat.view.tsx (1)
921-921: 依赖注入正确正确注入了
ChatFeatureRegistry服务,使组件能够访问消息摘要功能。packages/ai-native/src/browser/chat/chat.feature.registry.ts (3)
5-11: 导入语句更新正确添加了
IMessageSummaryProvider导入,支持新的消息摘要功能。导入顺序和格式与现有代码保持一致。
23-23: 私有字段定义恰当使用可选的私有字段存储消息摘要提供者,与现有的
imageUploadProvider模式保持一致。
33-39: 注册和获取方法实现标准
registerMessageSummaryProvider和getMessageSummaryProvider方法实现遵循了与imageUploadProvider相同的模式,保持了代码的一致性和可维护性。packages/ai-native/src/browser/chat/chat-manager.service.ts (3)
82-83: 依赖注入实现正确使用
@Autowired装饰器正确注入ChatFeatureRegistry服务,遵循了现有的依赖注入模式。
91-98: 构造函数参数传递一致在
fromJSON方法中正确地将chatFeatureRegistry传递给ChatModel和MsgHistoryManager构造函数,确保恢复的会话模型能够访问聊天功能注册表。
141-143: 新会话创建保持一致性在
startSession方法中同样将chatFeatureRegistry传递给ChatModel构造函数,确保新创建的会话和恢复的会话具有相同的功能访问权限。packages/ai-native/src/browser/chat/chat-model.ts (1)
300-306: 构造函数改动合理正确地将
ChatFeatureRegistry注入并传递给MsgHistoryManager,保持了良好的依赖管理。
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
packages/ai-native/src/browser/chat/chat-model.ts (1)
416-417: 错误日志可以更详细工具调用参数和结果解析失败时的错误日志可以包含更多上下文信息,便于调试。
Also applies to: 424-425
packages/ai-native/src/browser/model/msg-history-manager.ts (2)
67-71: 建议使用统一的日志机制Also applies to: 85-90, 140-144, 149-153, 167-171, 198-202, 205-209, 218-221, 229-229, 238-238, 243-243, 253-253, 263-267, 287-292
113-113: 内存压缩逻辑需要错误处理
🧹 Nitpick comments (3)
packages/ai-native/src/browser/chat/chat-model.ts (1)
456-471: Token 计算方法不够准确使用
JSON.stringify(currentHistory).length / 3来估算 token 数量是一个粗略的近似方法,可能导致不准确的结果。建议使用更准确的 token 计算方法:
-let tokenCount = JSON.stringify(currentHistory).length / 3; +let tokenCount = this.calculateTokenCount(currentHistory); +private calculateTokenCount(history: CoreMessage[]): number { + // 使用更准确的 token 计算逻辑 + // 例如:考虑不同语言的 token 特性,或使用专门的 token 计算库 + return history.reduce((total, message) => { + const content = Array.isArray(message.content) + ? message.content.map(c => typeof c === 'string' ? c : JSON.stringify(c)).join('') + : message.content; + return total + Math.ceil(content.length / 4); // 更合理的估算 + }, 0); +}packages/ai-native/src/browser/model/msg-history-manager.ts (2)
92-137: 内存压缩逻辑实现合理但可以优化内存压缩的整体逻辑是合理的,但可以考虑以下优化:
- 压缩策略可以更加灵活
- 可以考虑基于时间的压缩策略
- 压缩频率可以可配置
建议添加更灵活的压缩配置:
interface IMemoryConfig { shortTermSize: number; bufferSize: number; + compressionInterval?: number; // 压缩间隔(毫秒) + timeBasedCompression?: boolean; // 是否启用基于时间的压缩 + maxAge?: number; // 消息最大保留时间(毫秒) }
175-181: 异步压缩内存可能影响性能每次添加消息都会触发异步内存压缩,这可能在高频消息场景下影响性能。建议考虑防抖或节流机制。
建议添加防抖机制:
+private compressionTimer?: NodeJS.Timeout; +private static readonly COMPRESSION_DEBOUNCE_MS = 1000; private doAddMessage(message: IExcludeMessage): string { // ... 现有逻辑 - // 在添加新消息后尝试压缩记忆 - this.compressMemory().then(() => { - this._onMessageChange.fire(this.getMessages()); - }).catch((error) => { - console.error('[MsgHistoryManager] Error compressing memory', error); - }); + // 防抖压缩内存 + if (this.compressionTimer) { + clearTimeout(this.compressionTimer); + } + this.compressionTimer = setTimeout(() => { + this.compressMemory().then(() => { + this._onMessageChange.fire(this.getMessages()); + }).catch((error) => { + console.error('[MsgHistoryManager] Error compressing memory', error); + }); + }, MsgHistoryManager.COMPRESSION_DEBOUNCE_MS);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/ai-native/src/browser/chat/chat-manager.service.ts(3 hunks)packages/ai-native/src/browser/chat/chat-model.ts(3 hunks)packages/ai-native/src/browser/model/msg-history-manager.ts(8 hunks)packages/ai-native/src/browser/types.ts(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/ai-native/src/browser/types.ts
- packages/ai-native/src/browser/chat/chat-manager.service.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/ai-native/src/browser/chat/chat-model.ts (1)
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
MsgHistoryManager(26-294)
🔇 Additional comments (4)
packages/ai-native/src/browser/chat/chat-model.ts (1)
31-31: 新增导入看起来合理新增的
ChatFeatureRegistry导入与构造函数的变更保持一致。packages/ai-native/src/browser/model/msg-history-manager.ts (3)
8-24: 接口定义清晰合理新增的三个接口
IMemoryConfig、IMemorySummary和IToolCallInfo定义清晰,很好地封装了内存管理和工具调用的数据结构。
139-154: 工具调用管理功能实现正确
addToolCall和getToolCall方法实现简洁明了,提供了必要的工具调用信息管理功能。
48-72:Details
✅ Verification successful
构造函数变更需要验证调用方
构造函数现在需要
ChatFeatureRegistry参数,这是一个破坏性变更。同时还扩展了初始化数据的结构。运行以下脚本验证构造函数调用是否都已更新:
🏁 Script executed:
#!/bin/bash # 描述:查找所有 MsgHistoryManager 构造函数的调用 # 预期:所有调用都应该传递 ChatFeatureRegistry 参数 ast-grep --pattern $'new MsgHistoryManager($$$)'Length of output: 341
已验证所有 MsgHistoryManager 调用已传入 ChatFeatureRegistry 参数
- 在
packages/ai-native/src/browser/chat/chat-model.ts(第305行)使用了
new MsgHistoryManager(this.chatFeatureRegistry)- 在
packages/ai-native/src/browser/chat/chat-manager.service.ts(第95行)使用了
new MsgHistoryManager(this.chatFeatureRegistry, item.history)未发现遗漏或错误调用,无需进一步修改。
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/ai-native/src/browser/chat/chat-model.ts (2)
299-307: 构造函数依赖注入实现良好正确地将 ChatFeatureRegistry 作为必需参数添加到构造函数中,并传递给 MsgHistoryManager。这种依赖注入模式提高了代码的可测试性和模块化程度。
这解决了之前关于构造函数签名变更的评审意见。
342-473: 优秀的重构:将复杂方法拆分为专门的辅助方法很好地将之前复杂的 getMessageHistory 方法拆分为四个专门的私有方法:
processMemorySummaries(): 处理记忆总结processToolCall(): 处理工具调用processRecentMessages(): 处理最近消息limitTokens(): 控制 token 限制每个方法都遵循单一职责原则,大大提高了代码的可读性和可维护性。
这很好地解决了之前关于方法复杂性的评审意见。
🧹 Nitpick comments (1)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
15-20: 移除不必要的构造函数MockChatFeatureRegistry 的构造函数是多余的,因为它只是调用了 super() 而没有额外的逻辑。
-class MockChatFeatureRegistry extends ChatFeatureRegistry { - constructor() { - super(); - } -} +class MockChatFeatureRegistry extends ChatFeatureRegistry {}🧰 Tools
🪛 Biome (1.9.4)
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/ai-native/__test__/browser/chat/chat-model.test.ts(2 hunks)packages/ai-native/src/browser/chat/chat-model.ts(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
packages/ai-native/src/browser/chat/chat-model.ts (1)
ChatModel(296-526)
packages/ai-native/src/browser/chat/chat-model.ts (2)
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
MsgHistoryManager(26-294)packages/core-common/src/types/ai-native/index.ts (1)
IChatToolContent(366-369)
🪛 Biome (1.9.4)
packages/ai-native/__test__/browser/chat/chat-model.test.ts
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
🔇 Additional comments (4)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (2)
5-11: 测试导入更新正确正确添加了必需的导入,以适配 ChatModel 构造函数的新签名。导入的类都是测试所需的。
104-108: 测试设置正确更新以匹配新的构造函数签名正确地创建了 MockChatFeatureRegistry 实例并传递给 ChatModel 构造函数,这与 ChatModel 的新依赖注入模式保持一致。
packages/ai-native/src/browser/chat/chat-model.ts (2)
31-31: 正确添加了 ChatFeatureRegistry 导入导入语句正确添加,支持构造函数中的依赖注入。
475-480: getMessageHistory 方法重构简洁明了重构后的方法现在只负责编排各个辅助方法,逻辑清晰易懂:
- 处理记忆总结
- 处理最近消息
- 合并历史记录
- 应用 token 限制
这种设计模式让主方法成为一个清晰的协调器。
ff7466b to
53fe4d5
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
86-148: 内存压缩逻辑需要改进错误处理内存压缩功能的实现思路很好,但缺少对摘要生成失败的错误处理。
基于之前的审查意见,建议添加 try-catch 处理:
const summaryProvider = this.chatFeatureRegistry.getMessageSummaryProvider?.(); if (summaryProvider) { + try { const summary = await summaryProvider.generateMemorizedMessage(messageContents); if (summary) { this.memorySummaries.push({ content: summary, timestamp: Date.now(), messageIds: messagesToSummarize.map((msg) => msg.id), }); // 标记消息为已总结的逻辑... } + } catch (error) { + console.error('[MsgHistoryManager] Failed to generate memory summary:', error); + // 继续执行,不中断压缩流程 + } }
🧹 Nitpick comments (1)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
15-20: 简化 Mock 类实现MockChatFeatureRegistry 中的空构造函数是不必要的。
-class MockChatFeatureRegistry extends ChatFeatureRegistry { - constructor() { - super(); - } -} +class MockChatFeatureRegistry extends ChatFeatureRegistry {}🧰 Tools
🪛 Biome (1.9.4)
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
packages/ai-native/__test__/browser/chat/chat-model.test.ts(2 hunks)packages/ai-native/src/browser/chat/chat-manager.service.ts(3 hunks)packages/ai-native/src/browser/chat/chat-model.ts(3 hunks)packages/ai-native/src/browser/chat/chat.view.tsx(3 hunks)packages/ai-native/src/browser/model/msg-history-manager.ts(5 hunks)packages/ai-native/src/browser/types.ts(3 hunks)packages/core-common/src/types/ai-native/index.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/ai-native/src/browser/types.ts
- packages/ai-native/src/browser/chat/chat.view.tsx
- packages/ai-native/src/browser/chat/chat-manager.service.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/ai-native/src/browser/chat/chat-model.ts (1)
packages/ai-native/src/browser/model/msg-history-manager.ts (1)
MsgHistoryManager(26-269)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
packages/ai-native/src/browser/chat/chat-model.ts (1)
ChatModel(296-527)
🪛 Biome (1.9.4)
packages/ai-native/__test__/browser/chat/chat-model.test.ts
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
packages/core-common/src/types/ai-native/index.ts
[error] 442-446: The enum declaration should not be const
Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.
(lint/suspicious/noConstEnum)
🔇 Additional comments (16)
packages/core-common/src/types/ai-native/index.ts (1)
442-442: 类型定义更新正确支持消息摘要功能添加
isSummarized可选属性到IHistoryChatMessage接口是合理的,这将支持新的消息摘要和内存压缩功能。属性定义清晰,注释说明了用途。🧰 Tools
🪛 Biome (1.9.4)
[error] 442-446: The enum declaration should not be const
Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.(lint/suspicious/noConstEnum)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (2)
5-11: 测试导入更新正确正确导入了
ChatModel、ChatResponseModel和ChatFeatureRegistry,这些更新与 ChatModel 构造函数签名变更保持一致。
104-108: 测试正确适配新的构造函数签名测试已正确更新以注入 MockChatFeatureRegistry 实例到 ChatModel 构造函数中,这解决了构造函数签名变更带来的兼容性问题。
packages/ai-native/src/browser/chat/chat-model.ts (7)
299-307: 构造函数签名更新支持依赖注入正确地将
ChatFeatureRegistry作为必需参数注入到构造函数中,并传递给MsgHistoryManager。这种依赖注入模式支持了新的消息摘要功能。
342-368: 内存摘要处理逻辑清晰
processMemorySummaries方法实现了安全的 JSON 解析和内容过滤,正确处理了从MsgHistoryManager获取的内存摘要数据。错误处理和去重逻辑都很合理。
370-410: 工具调用处理实现完整
processToolCall方法正确处理了工具调用的参数解析、结果存储和消息历史构建。与MsgHistoryManager的集成也很好,能够正确存储工具调用信息。
412-419: JSON 解析错误处理得当
parseJsonSafely方法提供了安全的 JSON 解析,包含适当的错误日志和默认返回值。
421-454: 消息处理逻辑优化
processRecentMessages方法清晰地处理了最近消息的构建,正确过滤了不完整的响应并处理了不同类型的消息内容。
456-474: Token 限制逻辑合理
limitTokens方法实现了智能的消息历史裁剪,优先保留系统消息,并使用简单的 token 估算方法。
476-481: 重构后的主方法简洁清晰
getMessageHistory方法现在简洁明了,通过组合各个辅助方法来构建消息历史,提高了代码的可读性和可维护性。packages/ai-native/src/browser/model/msg-history-manager.ts (6)
8-24: 新增接口定义清晰新增的
IMemoryConfig、IMemorySummary和IToolCallInfo接口定义清晰,很好地支持了内存管理和工具调用跟踪功能。接口设计合理,字段命名清晰。
48-67: 构造函数正确支持新功能构造函数签名更新正确地注入了
ChatFeatureRegistry,并支持可选的工具调用和内存摘要数据初始化。这种设计支持了功能的灵活扩展。
150-157: 工具调用管理方法实现正确
addToolCall和getToolCall方法实现简洁正确,提供了基本的工具调用信息存储和检索功能。
172-180: 异步压缩调用处理得当在
doAddMessage中异步调用内存压缩并正确处理错误,不会阻塞消息添加流程。错误处理合理。
197-206: 新增公共方法设计合理
getMemorySummaries和setMemoryConfig方法提供了对内存摘要和配置的访问,API 设计清晰。
261-268: 序列化方法正确包含新数据
toJSON方法正确地包含了内存摘要和工具调用数据,确保了完整的状态序列化。
…y for summarization
53fe4d5 to
a2dc724
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/ai-native/src/browser/model/msg-history-manager.ts (2)
86-148: 内存压缩逻辑需要改进错误处理内存压缩机制设计合理,但异步操作缺少错误处理。如果
generateMemorizedMessage失败,可能会中断压缩流程。建议在异步调用周围添加 try-catch:
if (summaryProvider) { + try { const summary = await summaryProvider.generateMemorizedMessage(messageContents); if (summary) { this.memorySummaries.push({ content: summary, timestamp: Date.now(), messageIds: messagesToSummarize.map((msg) => msg.id), }); for (const msg of messagesToSummarize) { const existingMsg = this.messageMap.get(msg.id); if (existingMsg) { this.messageMap.set(msg.id, { ...existingMsg, isSummarized: true, }); } } } + } catch (error) { + console.error('[MsgHistoryManager] Failed to generate memory summary:', error); + } }
70-176: 建议统一日志机制文件中使用了多处
console.error语句。建议使用统一的日志框架以便在生产环境中控制日志级别。建议创建或使用现有的日志器:
import { getDebugLogger } from '@opensumi/ide-core-common'; export class MsgHistoryManager extends Disposable { private readonly logger = getDebugLogger('MsgHistoryManager'); // 替换 console.error 为: // this.logger.error('Error compressing memory', error); }
🧹 Nitpick comments (1)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
15-20: 优化 Mock 类构造函数Mock 类的空构造函数是不必要的,可以移除以简化代码。
-class MockChatFeatureRegistry extends ChatFeatureRegistry { - constructor() { - super(); - } -} +class MockChatFeatureRegistry extends ChatFeatureRegistry {}🧰 Tools
🪛 Biome (1.9.4)
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/ai-native/__test__/browser/chat/chat-model.test.ts(2 hunks)packages/ai-native/src/browser/chat/chat-manager.service.ts(3 hunks)packages/ai-native/src/browser/chat/chat-model.ts(3 hunks)packages/ai-native/src/browser/chat/chat.view.tsx(2 hunks)packages/ai-native/src/browser/model/msg-history-manager.ts(5 hunks)packages/ai-native/src/browser/types.ts(1 hunks)packages/core-common/src/types/ai-native/index.ts(1 hunks)packages/startup/entry/sample-modules/ai-native/ai-native.contribution.ts(2 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/ai-native/src/browser/types.ts
- packages/startup/entry/sample-modules/ai-native/ai-native.contribution.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/ai-native/src/browser/chat/chat.view.tsx
- packages/ai-native/src/browser/chat/chat-manager.service.ts
- packages/ai-native/src/browser/chat/chat-model.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (1)
packages/ai-native/src/browser/chat/chat-model.ts (1)
ChatModel(296-527)
🪛 Biome (1.9.4)
packages/ai-native/__test__/browser/chat/chat-model.test.ts
[error] 17-19: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
packages/core-common/src/types/ai-native/index.ts
[error] 443-447: The enum declaration should not be const
Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.
(lint/suspicious/noConstEnum)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: build (macos-latest, 20.x)
- GitHub Check: build (ubuntu-latest, 20.x)
- GitHub Check: unittest (macos-latest, 18.x, jsdom)
- GitHub Check: unittest (macos-latest, 18.x, node)
- GitHub Check: ubuntu-latest, Node.js 20.x
- GitHub Check: build-windows
- GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
- GitHub Check: unittest (ubuntu-latest, 18.x, node)
🔇 Additional comments (14)
packages/core-common/src/types/ai-native/index.ts (1)
443-443: LGTM!接口扩展合理添加
isSummarized可选属性用于标记消息是否已被总结,这与新增的内存压缩功能完美配合。属性类型和命名都很清晰。🧰 Tools
🪛 Biome (1.9.4)
[error] 443-447: The enum declaration should not be const
Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.(lint/suspicious/noConstEnum)
packages/ai-native/__test__/browser/chat/chat-model.test.ts (2)
4-11: 测试导入更新正确导入语句正确添加了
ChatModel、ChatResponseModel和ChatFeatureRegistry,与新的依赖注入架构保持一致。
104-108: 依赖注入适配正确测试正确适配了新的
ChatModel构造函数签名,通过注入 mock 的ChatFeatureRegistry实例来支持新的功能特性。packages/ai-native/src/browser/model/msg-history-manager.ts (11)
4-4: 依赖注入导入正确正确导入了
ChatFeatureRegistry以支持特性注册表的依赖注入。
8-25: 接口设计良好新增的接口设计合理:
IMemoryConfig提供了灵活的内存管理配置IMemorySummary完整记录了总结信息和相关元数据IToolCallInfo结构清晰地存储工具调用信息类型定义准确,字段命名清晰易懂。
29-31: 状态管理属性合理新增的私有属性设计得当:
memorySummaries用于存储内存总结toolCallMap用于工具调用追踪isCompressing防止并发压缩操作使用 Map 数据结构提供了高效的键值查找性能。
39-46: 内存配置设计合理默认配置参数合理:短期记忆保留10条消息,缓冲区5条。getter 方法返回配置副本防止外部修改,体现了良好的封装性。
48-67: 构造函数设计完善构造函数正确注入了
ChatFeatureRegistry依赖,并支持可选的初始化数据。数据恢复逻辑完整,包括消息、工具调用和内存总结的初始化。
82-84: 清理方法更新完整
clearMessages方法正确清理了新增的内存总结和工具调用数据,保持了状态一致性。
150-157: 工具调用管理方法实现正确
addToolCall和getToolCall方法实现简洁正确,提供了基础的工具调用存储和检索功能。
172-177: 异步内存压缩调用合理在添加新消息后异步触发内存压缩是合理的设计。错误处理使用 catch 捕获确保了程序稳定性,不会阻塞消息添加流程。
184-185: 消息排序逻辑正确按 order 字段升序排序保持了消息的时间顺序,确保了内存压缩和历史记录的正确性。
197-206: 访问器方法设计良好
getMemorySummaries和setMemoryConfig方法提供了对内存管理功能的外部访问接口。配置更新使用了展开运算符进行部分更新,设计灵活。
261-267: 序列化方法更新完整
toJSON方法正确包含了新增的内存总结和工具调用数据,确保了完整的状态序列化。
|
/next |
|
🎉 PR Next publish successful! 3.9.1-next-1749171169.0 |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4581 +/- ##
=======================================
Coverage 52.63% 52.63%
=======================================
Files 1685 1685
Lines 104065 104157 +92
Branches 22577 22610 +33
=======================================
+ Hits 54777 54826 +49
- Misses 40966 40999 +33
- Partials 8322 8332 +10
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
/next |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/ai-native/src/browser/chat/chat-model.ts (1)
299-307: 构造函数签名变更:确保测试用例已同步更新构造函数现在需要
ChatFeatureRegistry参数,这是一个破坏性变更。根据之前的评审意见,测试文件中的构造函数调用需要更新以传入必需的参数。packages/ai-native/src/browser/model/msg-history-manager.ts (1)
119-184: 内存压缩逻辑:需要改进错误处理和性能
compressMemory方法实现了复杂的内存管理逻辑,但存在几个需要改进的地方:private async compressMemory() { if (this.isCompressing) { return; } const messages = this.messageList; if (messages.length <= this.memoryConfig.shortTermSize) { return; } try { this.isCompressing = true; const latestExcessMessage = messages[messages.length - this.memoryConfig.shortTermSize - 1]; if (latestExcessMessage.isSummarized) { return; } this.messageBuffer.add(latestExcessMessage); if (this.messageBuffer.size() >= this.memoryConfig.bufferSize) { const messagesToSummarize = this.messageBuffer.messages; const summaryProvider = this.chatFeatureRegistry.getMessageSummaryProvider?.(); if (summaryProvider) { + try { const messageContents = messagesToSummarize.map((msg) => ({ role: msg.role, content: msg.content, })); const memorize = await summaryProvider.generateMemorizedMessage(messageContents); if (memorize) { this.memorySummaries.push({ content: memorize, timestamp: Date.now(), messageIds: messagesToSummarize.map((msg) => msg.id), }); for (const msg of messagesToSummarize) { const existingMsg = this.messageMap.get(msg.id); if (existingMsg) { this.messageMap.set(msg.id, { ...existingMsg, isSummarized: true, }); } } this.messageBuffer.clear(); } + } catch (error) { + console.error('[MsgHistoryManager] Failed to generate memory summary:', error); + // 继续执行,不中断压缩流程 + } } } } finally { this.isCompressing = false; } }
🧹 Nitpick comments (3)
packages/ai-native/src/browser/chat/chat-model.ts (1)
342-368: 记忆摘要处理:改进错误处理和数据验证
processMemorySummaries方法实现了良好的错误处理和数据过滤逻辑。建议进一步优化:private processMemorySummaries(): CoreMessage[] { const memorySummaries = this.history.getMemorySummaries(); if (memorySummaries.length === 0) { return []; } const processedSummaries = memorySummaries .map((summary) => { try { const parsed = JSON.parse(summary.content); return parsed.memory || parsed.content || summary.content; } catch { + console.warn('[ChatModel] Invalid JSON in memory summary, using raw content'); return summary.content; } }) - .filter((content) => content && content !== 'no_memory_needed') + .filter((content) => content && typeof content === 'string' && content.trim() !== '' && content !== 'no_memory_needed') .filter((content, index, self) => self.indexOf(content) === index);packages/ai-native/src/browser/model/msg-history-manager.ts (2)
26-51: 消息缓冲管理器:建议使用更具体的接口约束
MessageBufferManager接口和SimpleMessageBuffer实现提供了基础的缓冲功能,建议增强类型约束:export interface MessageBufferManager { - messages: IHistoryChatMessage[]; + readonly messages: readonly IHistoryChatMessage[]; add(message: IHistoryChatMessage): void; clear(): void; size(): number; + isEmpty(): boolean; }
208-217: 异步压缩调用:改进错误处理在
doAddMessage中异步调用compressMemory是合理的设计,但错误处理可以进一步优化:private doAddMessage(message: IExcludeMessage): string { // ... existing code ... this.messageMap.set(id, msg); - // 在添加新消息后尝试压缩记忆 this.compressMemory().catch((error) => { - // eslint-disable-next-line no-console - console.error('[MsgHistoryManager] Error compressing memory', error); + console.error('[MsgHistoryManager] Memory compression failed for message:', id, error); + // 可以考虑添加重试机制或降级策略 }); - // 无论压缩是否完成,都触发消息变更事件 this._onMessageChange.fire(this.getMessages()); return id; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/ai-native/src/browser/chat/chat-model.ts(3 hunks)packages/ai-native/src/browser/model/msg-history-manager.ts(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: unittest (ubuntu-latest, 18.x, jsdom)
- GitHub Check: unittest (macos-latest, 18.x, node)
- GitHub Check: unittest (macos-latest, 18.x, jsdom)
- GitHub Check: unittest (ubuntu-latest, 18.x, node)
- GitHub Check: build (ubuntu-latest, 20.x)
- GitHub Check: build (macos-latest, 20.x)
- GitHub Check: ubuntu-latest, Node.js 20.x
- GitHub Check: build-windows
🔇 Additional comments (9)
packages/ai-native/src/browser/chat/chat-model.ts (4)
31-31: 依赖注入:确认新导入符合架构要求新增的
ChatFeatureRegistry导入建立了对特性注册表的依赖关系,这符合依赖注入模式的良好实践。
412-419: JSON 解析工具:LGTM!
parseJsonSafely方法提供了良好的错误处理和日志记录,这是一个实用的工具方法。
473-478: 重构后的消息历史方法:LGTM!重构后的
getMessageHistory方法结构清晰,职责分离良好,显著提高了代码的可维护性。这解决了之前评审中提到的方法过于复杂的问题。
421-451:Details
✅ Verification successful
消息处理逻辑:验证过滤条件
processRecentMessages方法的过滤逻辑需要验证isSummarized字段的正确性:// 建议添加调试日志以跟踪过滤行为 const allMessages = this.history.getMessages(); const filteredMessages = allMessages.filter((msg) => !msg.isSummarized); console.debug(`[ChatModel] Filtered ${allMessages.length - filteredMessages.length} summarized messages`);请运行以下脚本验证
isSummarized字段的使用:
🏁 Script executed:
#!/bin/bash # 描述:验证 isSummarized 字段在代码库中的使用情况 # 预期:应该在 IHistoryChatMessage 接口中定义并在相关代码中正确使用 ast-grep --pattern $'isSummarized'Length of output: 33
为了确认
isSummarized字段是否在仓库中正确定义和使用,请运行以下脚本:此脚本将帮助我们定位该字段的声明位置及其在项目中的使用情况,以便进一步验证过滤逻辑是否可靠。
🏁 Script executed:
#!/bin/bash # 在整个仓库中搜索 isSummarized 的所有引用 rg -n "isSummarized" . # 搜索 IHistoryChatMessage 接口或相关类型定义 rg -n "interface.*IHistoryChatMessage" .Length of output: 599
isSummarized 字段验证通过
IHistoryChatMessage 接口(packages/core-common/src/types/ai-native/index.ts:440)中已声明可选字段
isSummarized,并在以下位置正确使用:
- chat-model.ts(packages/ai-native/src/browser/chat/chat-model.ts:426):过滤逻辑
.filter(msg => !msg.isSummarized)- msg-history-manager.ts(packages/ai-native/src/browser/model/msg-history-manager.ts:138/171):设置和判断
isSummarized过滤逻辑已被正确配置,行为可靠。若需跟踪运行时过滤情况,可按需添加调试日志,无其他改动必要。
packages/ai-native/src/browser/model/msg-history-manager.ts (5)
4-4: 新增接口设计:结构清晰,类型安全新增的接口
IMemoryConfig、IMemorySummary和IToolCallInfo设计合理,为内存管理和工具调用跟踪提供了良好的类型安全保障。Also applies to: 8-25
73-94: 构造函数更新:依赖注入实现正确构造函数正确接受了
ChatFeatureRegistry参数,并支持可选的初始化数据,这与ChatModel的更新保持一致。
186-193: 工具调用管理:LGTM!
addToolCall和getToolCall方法实现简洁明了,提供了基础的工具调用 CRUD 操作。
233-242: 内存配置管理:LGTM!
getMemorySummaries和setMemoryConfig方法提供了良好的配置访问接口,支持部分配置更新。
297-304: 序列化增强:结构完整
toJSON方法正确包含了新增的内存摘要和工具调用数据,确保了完整的状态序列化。
|
🎉 PR Next publish successful! 3.9.1-next-1749175927.0 |
Types
Background or solution
Changelog
Summary by CodeRabbit
新功能
改进
修复