Skip to content

feat(message-blocks): introduce new message block types and middlewar… #4571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

MyPrototypeWhat
Copy link
Collaborator

@MyPrototypeWhat MyPrototypeWhat commented Apr 8, 2025

重新定义message结构,数据库可以更新对应索引(但是没有想好怎么写),通过旧数据的metadata\reasoning_content\translatedContent大概能拆分出来block

  • Message还需要精简,尽量保证只保存与渲染相关的属性
  • 这样划分了Message之后颗粒度更细,可以精确到对应的某个组件,对于不同blockui和性能可以精确管控

…e for handling message updates

- Added new types for message blocks including MainText, Thinking, Translation, Code, Image, ToolCall, ToolResult, KnowledgeCitation, WebSearch, File, and Error blocks.
- Implemented middleware to manage message block mapping and updates in Redux, enhancing the handling of message states and blocks.
- Introduced LRU caching for efficient message block retrieval and management.
@MyPrototypeWhat
Copy link
Collaborator Author

MyPrototypeWhat commented Apr 8, 2025

重构后架构的优点

重构后的架构采用了嵌套 LRU 缓存和自定义 hooks 的组合,带来了多方面的优势:

1. 缓存管理优化

  • 分层缓存策略:外层缓存管理活跃话题(最多100个, 有待商榷 ),内层缓存管理每个话题的消息块(最多100个,有待商榷),形成两级缓存结构
  • 智能过期机制:话题缓存1天,消息块缓存1小时(有待商榷),自动清理不活跃内容
  • 内存使用优化:通过限制缓存数量,避免内存泄漏和过度占用

2. 数据流优化

  • Redux 与缓存分离:Redux 只存储消息的基本结构和块 ID 引用,不存储完整的块内容
  • 按需加载:消息块内容只在需要时从缓存中获取,减少初始加载时间
  • 增量更新:只更新发生变化的块,避免不必要的重渲染(

3. 自定义 Hooks 的优势

  • 依赖收集:类似 SWR 的依赖收集机制,自动追踪组件使用的消息块

4. 性能提升

  • 减少 Redux 状态大小:Redux 中只存储轻量级的消息结构和块 ID
  • 精确更新:只有使用特定消息块的组件才会在块更新时重新渲染
  • 避免重复请求:缓存机制避免重复获取相同的数据

5. 架构灵活性

  • 关注点分离:数据获取、缓存管理和 UI 渲染各司其职
  • 可扩展性:易于添加新的消息块类型和处理逻辑
  • 测试友好:各层可以独立测试,提高代码质量

6. 用户体验改进

  • 更快的响应时间:缓存机制减少等待时间
  • 更流畅的交互:精确更新减少不必要的重渲染

这种架构特别适合处理大量消息和复杂 UI 的聊天应用,能够在保持良好性能的同时提供流畅的用户体验。

@MyPrototypeWhat
Copy link
Collaborator Author

graph TD
    A[Dispatch<br>发起 Action] --> B[Redux 中间件]
    B -->|同步数据| C[messageBlockMap<br>全局缓存]
    B -->|持久化| D[IndexedDB<br>数据库]
    C -->|获取缓存| E[topicCache LRU<br>按 topicId 分组]
    D -->|加载历史数据| E
    E --> F[CRUD 操作<br>增删改查 MessageBlock]
    B -->|更新状态| G[Redux Store<br>存储活跃消息元数据]
    F -->|提供数据| H[自定义 Hook<br>收集依赖(如 SWR)]
    G -->|提供元数据| H
    H -->|返回最新数据| I[渲染组件]
    I -->|按需加载| H

    %% 定义样式
    classDef action fill:#f9f,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef middleware fill:#bbf,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef cache fill:#dfd,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef db fill:#ffb,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef operation fill:#dfd,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef store fill:#bbf,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef hook fill:#ffb,stroke:#333,stroke-width:2px,border-radius:5px;
    classDef render fill:#f9f,stroke:#333,stroke-width:2px,border-radius:5px;

    %% 应用样式
    class A action;
    class B middleware;
    class C cache;
    class D db;
    class E cache;
    class F operation;
    class G store;
    class H hook;
    class I render;

    %% 调整边样式
    linkStyle default stroke:#666,stroke-width:2px;
Loading

@DeJeune
Copy link
Collaborator

DeJeune commented Apr 8, 2025

如果想要拼接消息,比如达到max_token被截断的html,拼接到一起渲染如何做?需要添加数据结构哪些字段?

@MyPrototypeWhat
Copy link
Collaborator Author

如果想要拼接消息,比如达到max_token被截断的html,拼接到一起渲染如何做?需要添加数据结构哪些字段?

与文本消息有什么区别吗,或者有什么标识区分吗

@DeJeune
Copy link
Collaborator

DeJeune commented Apr 9, 2025 via email

@DeJeune
Copy link
Collaborator

DeJeune commented Apr 9, 2025

我感觉没区别,就是不完整的代码块(但是要隐藏一个user消息的显示,然后还要判断代码块是否被截断) MyPrototypeWhat @.> 于 2025年4月9日周三 上午9:18写道:

如果想要拼接消息,比如达到max_token被截断的html,拼接到一起渲染如何做?需要添加数据结构哪些字段? 与文本消息有什么区别吗,或者有什么标识区分吗 — Reply to this email directly, view it on GitHub <#4571 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQCNHH6ZHLFNFJJGOIGZJW32YRYNTAVCNFSM6AAAAAB2WXUW7SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOOBYGA2DEOJUG4 . You are receiving this because you commented.Message ID: @.
> MyPrototypeWhat left a comment (CherryHQ/cherry-studio#4571) <#4571 (comment)> 如果想要拼接消息,比如达到max_token被截断的html,拼接到一起渲染如何做?需要添加数据结构哪些字段? 与文本消息有什么区别吗,或者有什么标识区分吗 — Reply to this email directly, view it on GitHub <#4571 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQCNHH6ZHLFNFJJGOIGZJW32YRYNTAVCNFSM6AAAAAB2WXUW7SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOOBYGA2DEOJUG4 . You are receiving this because you commented.Message ID: @.***>

我想到了一个,就是给消息块加上isVisible

- Introduced a new Redux slice for managing messages, including actions for setting the current topic, loading state, error handling, and message updates.
- Added utility functions for creating various message block types, enhancing the structure and management of message content.
- Updated message type definitions to include timestamped block references, improving the tracking of message block states.
@MyPrototypeWhat
Copy link
Collaborator Author

message大体上分为text\file\img 三种,在text中分为了多种block,添加了createis工具函数帮助创建和判断消息类型

@MyPrototypeWhat
Copy link
Collaborator Author

一顿分析+与一众大模型深度交流 ⬇️

redux+全局嵌套LRU 这种方案性能好,但是重构范围太大
找到一个折中方案 ⬇️
redux中新增messageBlock,使用createEntityAdapter高效管理,#4660
可以先试试这种这种方案,此pr作为最终手段,也可能用不到这个

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants